拷贝构造函数
1、什么叫拷贝构造函数
拷贝构造函数是一种特殊的构造函数,它唯一的参数是源对象的引用,是const类型,经常被称为X(X&),它叫做类X的外在表现
例:class A{
public:
A(){}
A(const A&){
cout<<"A(A&)"<<endl;
}
};
2、为什么要使用拷贝构造函数
由于拷贝构造函数是通过传值方法传递和返回,位拷贝是通过传地址方法传递,使用拷贝构造函数能够防止编译器进行位拷贝。关于位拷贝和值拷贝的区别,这篇文章讲的很清楚:http://blog.csdn.net/liam1122/article/details/1966617
3、调用拷贝构造函数的情形
A、一个对象作为函数参数,以值传递的方式传入函数体
B、一个对象作为函数的返回值,以值传递的方式从函数返回
C、一个对象用于给另一个对象初始化
4、默认拷贝构造函数
如果没有创建拷贝构造函数,C++编译器将自动创建一个默认拷贝构造函数。引用上面的例子,并扩展如下:
class B{
string id;
public:
B(const string& ident=""):id(ident){} //不是拷贝构造函数
void print(const string& msg="") const{
if(msg.size()!=0){
cout<<msg<<": ";
}
cout<<id<<endl;
}
};
class AB{
A a;
B b;
public:
AB():b("AB()"){}
void print(const string& msg="") const{
b.print(msg);
}
};
int main(){
AB ab;
ab.print("Constens of ab"); //输出Constens of ab:AB()
cout<<"Calling AB copy-constructor"<<endl;
AB ab2=ab; //输出A(A&)
ab2.print("Constents of ab2"); //输出Constens of ab2:AB()
}
为了对使用组合的类创建拷贝构造函数,编译器递归的为所有的成员对象和基类调用拷贝构造函数。如果成员对象还含有别的对象,那么后者的拷贝构造函数也将被调用。这里,通过AB ab2=ab调用了A的拷贝构造函数。因为B没有拷贝构造函数,所以编译器为它创建了一个默认拷贝构造函数,该拷贝构造函数仅执行了位拷贝。
PS:编译器获得一个拷贝构造函数的过程被称为成员方法初始化。
5、防止按值传递
如果想保证一个对象永远不会被通过按值传递方式传递,则只需要声明一个私有拷贝构造函数,可以不必去定义它。
例:class MyClass{
int i=0;
MyClass(const MyClass&); //防止对象按值传递
public:
MyClass(int ii=0):i(ii){}
};