形式如此,用一个对象给另一个同类对象初始化
X::X(const X& x)
{
a = x.a;
b = x.b;
}
如果在类中没有定义拷贝构造函数,编译器会自行定义一个。如果类带有指针变量,并有动态内存分配,则它必须有程序员自定义的一个拷贝构造函数。
-
拷贝构造函数使用的场景
- 显示初始化操作
X xx = x;
- 对象做参数传递给函数的时候
- 函数传回一个类对象时
- 显示初始化操作
-
不同场景下构造函数的使用
- 显示初始化操作
X x0;
void foo_bar()
{
X x1(x0);
X x2 = x0;
X x3 = X(x0);
}
会被转换成下面的过程(两个阶段)1.定义类对象 2.调用对象拷贝构造函数
X x0;
void foo_bar()
{
X x1;
X x2;
X x3;
x1.X::X(x0);
x2.X::X(x0);
x3.X::X(x0);//调用 X::X(const X& xx)
}
- 参数的初始化
void foo(X x0);//声明
X xx;
foo(xx);
会被转换成实际如下:
voif foo(X& x0);//转化为引用
X _temp0;//编译器产生出来临时对象
_temp0.X::X(xx);
foo(_temp0);
- 返回值的初始化
X bar()
{
X xx;
//处理xx
return xx;
}
转化
void
bar( X&__result )//传入引用类型的返回值
{
X xx;
xx.X::X();//调用默认构造函数
//....处理xx
__result.X::XX(xx);//copy构造函数
return;
}
将编译器必须把程序中每一个bar都转化了
X xx = bar();
//会被转化为
X xx;
bar(xx);
bar().memfunc();//执行bar返回值的成员函数
//会被转化为
X __temp0;
( bar(__temp0),__temp0).memfunc();
//函数指针
X (*pf)();
pf = bar;
//被转化为
void (*pf)(X&);
pf = bar;
- 对于返回一个对象(即3)编译器做的优化:NRV(named return value)
//原函数
X bar()
{
X xx;
//处理xx
return xx;
}
//转化为
void
bar( X&__result )//传入引用类型的返回值
{
X xx;
xx.X::X();//调用默认构造函数
//....处理xx
__result.X::XX(xx);//copy构造函数
return;
}
//优化为
void
bar ( X&__result)
{
__result.X::X();
//直接处理__result
return;
}
将要返回的
网友评论