拷贝构造函数调用时机
class Stud { ....} ;
Stud stu1 ={....} ;
1 使用一个对象初始化另一个对象
Stud stu2 = stu1 ;
2 Stu stu2 (stu1) ;
3 对象作为实参传给函数形参
printf_stu(const Stud st )
prittf_stu( stu1 ) ;
4 函数的返回值是一个对象
拷贝构造函数形式:
Stud ( const Stud & st ) 其中const是可选项
匿名对象
Stud g(){ Stud s1(....) ; return s1 ;}
返回一个匿名对象:用s1创建了一个匿名对象,此时会调用拷贝构造函数
void p() { g() ; }
此函数调用时,会执行一次析构函数,释放s1所占空间,函数调用完成后,再调用析构函数释放匿名对象所占空间。
若 用 Stud stu2 = g() ; 则此语句后,匿名对象被扶正,(编译器已经优化,不会调用拷贝构造函数)即变成stu2,不会被析构。
若 Stud stu2 ; stu2 = { ...} ; stu2 = g() ; 【此处会调用对象的赋值运算】然后匿名对象变无用,同样会调用析构函数释放匿名对象所占空间
Stud(1 ,2,3) ; 将调用构造函数,生成匿名对象,该匿名的生命周期仅为该语句,即先调用玩构造函数即刻
请注意对象的赋值与初始化的区别
浅拷贝:只是将成员变量的值复制(例如里面是指针,则只是将地址进行复制)
默认的拷贝构造函数是浅拷贝
深拷贝构造函数: // 拷贝时,内存空间重新分配,然后再指向相同的值,即为深拷贝。
Stud (const Stud & stu1 )
{
len = strlen(stu1.name);
name = (char *) malloc( len+1 ) ;
strcpy(name,stu1.name);
}
对象使用默认的赋值操作符也是浅复制。 如果类成员中包含指针变量,则同样会出现浅复制所出现的问题。解决办法就是对自己对复制操作符进行重载。 operator =() ;
构造函数初始化列表 解决: 在一个类B中,有成员变量(类A对象),(其中类A设计了构造函数)
根据构造函数的调用规则,设计A的构造函数必须要使用,否则没有机会初始化A ,如果包含多个类,则在调用子类的构造函数时是按照类成员的定义顺序调用,不是按照初始化列表来调用。析构调用顺序与构造顺序相反。
ClassName() : A(1) , b(2) { ... }
列表初始化还用来给类的const成员变量初始化
在构造函数中调用构造函数如果没有对象来接收所调用的构造函数生成的匿名对象,将会直接将匿名对象析构。 即构造函数里所调用构造函数没有任何作用