复制构造函数的操作
像default constructor一样 如果一个class没有声明一个复制构造函数,就会有隐式的声明出现。跟之前一样,C++标准会把复制构造函数分为有用的以及无用的,只有有用的实例才会被合成到程序之中,决定一个copy constructor是否是trivial的标准在于class是展现出所谓的bitwise copy semantics。
bitwise copy sematics
以一段代码展示:
class Word
{
public:
Word(const char*);
~Word(){delete [] str;}
private:
int cnt;
char *str;
}
这种声明展现了bitwise copy semantics(逐为拷贝),这时类的初始化并不需要以函数调用完成,只需要按位拷贝。
不是bitwise copy sematics
根默认构造函数类似分四种情况:
1.当class内含一个class object而后者声明有一个复制构造函数时(编译器有义务调用其复制构造函数),就会生成一个non-trivial 复制构造函数。
2.当class继承自一个base class而后者存在一个复制构造函数时,编译器有义务调用基类的复制构造函数。
3.当class声明一个或多个virtual functions时。
4.当class派生自一个继承串链,其中有一个或多个virtual base classes.
前两种情况,编译器必须将member或base class的copy constructors调用操作安插到合成的复制构造函数中。后面两种情况相对复杂:
有虚函数的时候重新设定vptr
这种情况如果是以派生类初始化基类,必须冲洗设定vptr指向基类的虚表。
处理virtual base class subject
虚基类的存在需要特殊处理。一个类对象如果以另一个对象作为初值,而后者有一个虚基类子部分,那么bitwise copy semantics就会失效。编译器需要合成一个复制构造函数,安插一些代码设定虚基类指针或偏移,对每一个members执行必要的memberwise初始化,以及执行其他的内存相关操作。
编译器调用复制构造函数的策略以及这些策略如何影响我们的程序
编译器优化操作NRV:
以一段代码来展示:
X bar()
{
X xx;
return xx;
}
//经过NRV优化之后:
void bar(X &__result)
{
__result.X::X();
return;
}