1. 默认构造函数:只有当一个类没有定义构造函数的时候,编译器才会自动生成一个默认构造构造函数。
如下代码是编译会有问题:
class Myclass
{
public:
Myclass(int i);//自定义构造函数
private:
int m_data;
};
//因为存在自定义构造函数,所以编译器不会生成一个默认构造函数Myclass(){},所以会出错!
Myclass A;//error
//所以你最好人工添加一个默认构造函数Myclass(){}
{
public:
Myclass(int i);//自定义构造函数
private:
int m_data;
};
//因为存在自定义构造函数,所以编译器不会生成一个默认构造函数Myclass(){},所以会出错!
Myclass A;//error
//所以你最好人工添加一个默认构造函数Myclass(){}
2. 复制构造函数和赋值操作符
如果你的类中没有定义这两个东东,那么系统也会给你合成它们,他们的原型如下:
Myclass(const Myclass &);//也可以不要const限定符
Myclass & operator=(const Myclass &);//也可以不要const限定符
Myclass & operator=(const Myclass &);//也可以不要const限定符
那什么时候会调用复制构造函数呢?
如下:
Myclass A;
Myclass B(A);//调用复制构造函数
Myclass C=A;//这里不是调用赋值操作符,是调用复制构造函数
//当Myclass类型的对象传递给一个函数,或者函数返回该类型的对象的时候,会隐式调用复制构造函数,如:
Myclass Func(Myclass T);
//那么调用这个函数的时候,会调用两次复制构造函数,但是构造返回的对象是临时对象,调用过程结束,那个对象也就消亡了。
//以下是调用赋值操作符,看看与上面的不同吧!
Myclass A(1),B;
B=A;//调用赋值操作符
Myclass B(A);//调用复制构造函数
Myclass C=A;//这里不是调用赋值操作符,是调用复制构造函数
//当Myclass类型的对象传递给一个函数,或者函数返回该类型的对象的时候,会隐式调用复制构造函数,如:
Myclass Func(Myclass T);
//那么调用这个函数的时候,会调用两次复制构造函数,但是构造返回的对象是临时对象,调用过程结束,那个对象也就消亡了。
//以下是调用赋值操作符,看看与上面的不同吧!
Myclass A(1),B;
B=A;//调用赋值操作符
如果你要你的类不允许复制构造,那么你可以将复制构造函数定义成private。
楼主总结得很精辟呀!
“在这个例子里:Myclass Func(Myclass T); 当这个函数在主程序里运行时,会调用2次复制构造函数”,(我接在后面补充一下:)他们分别是一次在传参数时调用,一次在函数结束返回T对象而产生的临时对象时调用。那么会在函数结束时,就会调用2次析构函数。就是说 这三种不同的构造函数都对应一个析构函数。 ^_^
我们俩完全属于自娱自乐哈哈
如果一个类有动态分配内存,那么最好要为这个类申明一个拷贝构造函数和一个赋值操作符
因为默认的赋值操作符和拷贝构造函数是直接对数据成员赋值
那么就有可能出现内存泄漏和一个对象离开生存空间,另一个对象也就离开了生存空间!