C++ 基础总结

来源:互联网 发布:数据类型 js 编辑:程序博客网 时间:2024/04/30 15:42

1.类的接口调用顺序不能规定顺序:即以任何顺序调用都不应发生异常。
2.当一个类的对象超出其作用域时, 编译器即会调用其析构函数...
    {
    Test t;
    }
    cout<<"end";
    //在cout<<"end";之前,会看到类Test的析构函数的输出...由汇编代码也可看出Test::~Test()的调用..
3.string:
  string的c_str()实际上返回的是string的数据成员char*的指针. 
  如:char * str_p=const_cast<char*>str.c_str();
      然后用str_p修改其指向的字符数组的值,则: string s的值也会发生改变.
4.用delete 释放一个 已经不存在的 对象,异常..
  用delete 释放一个对象,则编译器会 在其之前调用该对象指针指向对象的析构函数.
  delete obj_p=NULL;//不会发生异常..
 
5.对于任何一个类,如果作者没有重载某些运算符,编译器默认地重载了必要的运算符...如:赋值=,.......
 
!!! 当传值来传递和返回该类的对象 都会调用拷贝构造函数.
static数据成员必须在任何程序块之外定义..
 
class C{
    static int x;// declared
    //..
}
int C::x; //define...即使x为私有的也应如此..
 
6.对任何一个函数(方法),不要轻易地返回一个对象,或一个对象的引用.... 返回的*(new C) ; 除外..
  //若返回的对象引用,并且该对象在该函数中定义,则当发生其它函数调用时,可能覆盖这个对象所在的区域.
  //若返回一个对象时,一定要处理好 operator+()与 拷贝构造函数Test(Test& t):data(NULL){}
  
    !!!!!!!!有动态数据的成员了处理!!!!!!!
    Test(const Test &t):data(NULL),length(0){         
        cout<<"调用拷贝构造函数:"<<data<<endl;
        copyInfo(t);
    }
    Test& operator=(const Test &t){
        cout<<"调用operator=函数data:"<<data<<endl;
        if(this!=&t)copyInfo(t);
        return *this;     
    }
    void copyInfo(const Test& t){
        delete [] data;
        if(0==t.data){data=0;length=0;return;}        
        data=new int[length=t.length];
        for(int i=0;i<length;i++){
            data[i]=t.data[i];
            cout<<" t.data[i] :"<<t.data[i]<<endl;
        }
    } 
 
如:          
/* Test func(){
    Test t(15,"show");
    return t; //在此时,t的析构函数会被调用...
   }
*/
 
 
 
class Test {
public :
    Test():data(NULL),length(0){         
        cout<<"调用默认构造函数."<<endl;
    }
    Test(int len,string name){
        cout<<"调用构造函数."<<endl;
        data= new int[length=len];
        this->name=name;
        set();
    }
    Test(const Test &t):data(NULL),length(0){         
        cout<<"调用拷贝构造函数:"<<data<<endl;
        copyInfo(t);
    }
    ~Test(){
        cout<<"释放data :"<<name.c_str()<<endl;
        delete[]data;
        data=NULL;
    }
    void set(){
        for(int i=0;i<length;i++)data[i]=i;
    }
    void show()const{
        for(int i=0;i<length;i++){
            cout<<i<<" "<<data[i]<<" "<<endl;             
        }
    }
    Test& operator=(const Test &t){
        cout<<"调用operator=函数data:"<<data<<endl;
        if(this!=&t)copyInfo(t);
        return *this;     
    }
private:
    int *data;
    int length;
    string name;
    void copyInfo(const Test& t){
        delete [] data;
        if(0==t.data){data=0;length=0;return;}        
        data=new int[length=t.length];
        for(int i=0;i<length;i++){
            data[i]=t.data[i];
            cout<<" t.data[i] :"<<t.data[i]<<endl;
        }
    }
};
 
 
Test func(){
    Test t(15,"show");
    return t;
}
 
int main(){
     func(); //顺序: 调用构造函数A->调用拷贝构造函数B->调用析构函数A->调用析构函数B
 
     Test t=func();//顺序:调用构造函数A->调用拷贝构造函数B->调用析构函数A->调用operator=  ->调用析构函数B
}
 
 
7.setfill,setw等需要带参操作符需要头文件 <iomanip>
 
8.对文件操作: <fstream>  ifstream infile; ofstream outfile; if(!infile)文件没打开..
 
9.static_cast<float>(float_var)
  const_cast<char*>(c_c_p) //去掉常数特性
  reinterpret_cast指针类型的改变
  dynamic_cast
10.匿名enum主要用途就是定义常量: enum{size=10;}
 
11. getline(infile,string_buff);   //如果设有读入字符,将返回 false
 
12. string :erase,replace, find(s2,index):若没有找到s2,将返回一个无穷大..
 
13. xxx(const yyy &c)const;
 
14. 例外处理: try{ s.erase(index,len);}catch(out_of_range){}
    try{ a=new T;}catch(bad_alloc){}
 
    try{}catch(){}是怎么实现的???
 
15.无名空间: namespace{}-->相当于c中static
   无名enum:  常量
   无名union: 普通变量

原创粉丝点击