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: 普通变量
C++ 基础总结
最新推荐文章于 2023-12-22 12:10:16 发布