当用一个已初始化过了的自定义类类型对象去初始化另一个新构造的对象的时候,拷贝构造函数就会被自动调用。也就是说,当类的对象需要拷贝时,拷贝构造函数将会被调用。以下情况都会调用拷贝构造函数:
一个对象以值传递的方式传入函数体
一个对象以值传递的方式从函数返回
一个对象需要通过另外一个对象进行初始化。
如果在类中没有显式地声明一个拷贝构造函数,那么,编译器将会自动生成一个默认的拷贝构造函数,该构造函数完成对象之间的位拷贝(浅拷贝)。
在某些状况下,类内成员变量需要动态开辟堆内存,如果实行位拷贝,也就是把对象里的值完全复制给另一个对象,如A=B。这时,如果B中有一个成员变量指针已经申请了内存,那A中的那个成员变量也指向同一块内存。这就出现了问题:当B把内存释放了(如:析构),这时A内的指针就是野指针了,出现运行错误。
(1)当用类的一个对象去初始化该类的另一个对象时 如
Point a(1,2);
Point b(a);//用对象a初始化对象b 也可以写成b=a
(2)如果函数的形参是类的对象,调用函数时,进行形参和实参结合时 如
void f(Point p)//Point是类
{
cout<<"pgetX";
}
int main()
{
Point a(1,2);
f(a)//函数的形参为类的对象,当掉用函数时,复制构造函数被调用
}
(3)如果函数的返回值是类的对象,函数执行完成返回调用时 如
void g()
{
Point a(1,2);
return a;//函数的返回值是类的对象,返回函数值时,复制构造函数被调用
}
int ()
{
Point b;
b=g();
return 0;
}
class A{
//
};
A a = new A();
A b = a; //拷贝构造函数
A c;
c = a; //赋值函数
从语言规范的角度来说,这只是一种规定而已。
C++标准128第2段提到:
A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&, volatile X& or const volatile X&, and either there are no other parameters or else all other parameters have default arguments
翻译过来就是:
如果类X的一个非模板构造函数的第一个参数的类型是 X&,const X&,volatile X& 或 const volatile X& 中的一个,而且这个构造函数要么没有其他参数,要么其他参数都有默认值,那么这个构造函数就是拷贝构造函数。
这是人为的规定。
从逻辑的角度来说,因为从参数的传递本身就是拷贝。如果不使用引用类型,拷贝构造函数传递参数时又会调用拷贝构造函数,造成循环调用。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)