-
类的默认合成拷贝构造函数会拷贝数组成员。
-
拷贝构造的发生条件及优化
-
实参传递给非引用类型形参
class A(B)
-
函数返回类型为非引用类型并返回一个对象。 注意编译器可能会使用ROV(Return Value Optimization)优化,导致并没有发生拷贝构造.
-
返回值优化(RVO),即通过将返回值所占空间的分配地点从被调用端转移至调用端的手段来避免拷贝操作。返回值优化包括具名返回值优化(NRVO)与无名返回值优化(URVO),两者的区别在于返回值是具名的局部变量还是无名的临时对象
-
RVO发生的条件:
- return 的值类型与 函数声明的返回值类型相同
- return的是一个局部对象
// g++ 默认执行NRVO与URVO优化,vs不确定 class B { public: B(int p){ cout << "in Direct init " << endl; a = p; } B(const B& rp){ cout << "in copy init" << endl; a = 5; } B& operator= (const B& ep){ cout << "in operator= init " << endl; a = 6; return *this; } int a ; }; B RetB1() { return B(1);//无名临时对象 } B RetB2() { B b(2); return b;//named局部对象 } int main() { B b1 = RetB1();// URVO优化,未发生拷贝 B b2 = RetB2();// NRVO优化,未发生拷贝 }
-
-
类对象使用=初始化时。
B b(2); B b1 = b;// 拷贝构造
注意若右值是临时变量导致 右值拷贝优化
-
右值拷贝优化:即当类类型的临时对象=初始化同类型的对象时,通过直接利用该临时对象的方法来避免拷贝操作。
这项优化只能用于右值(临时对象),不能用于左值int main { B a(9); B b1 = 8;// 8初始化的临时对象,直接作为b1. cout << " b1.a = " << b1.a<< endl; b1 = 9; // 因为右值是B(9)临时变量,=重载函数的引用必须是const的 cout << " b1.a = " << b1.a<< endl; getchar(); return 0; }
-
-
花括号列表初始化元素为类类型的数组。
-
因为以上条件下都可能发生隐士初始化,所以一般不对拷贝初始化做explicit
-
-
标准库要求保存在容器中的类型都要有拷贝赋值运算符 T& operator=(const T& ),否则会使用默认的合成拷贝赋值运算符。
-
类内成员默认初始化在构造函数体之前完成,默认析构在析构函数体之后开始。
-
类默认构造(包括拷贝)无法完成对const或引用成员的初始化。
c++ 拷贝控制需要注意的几点
最新推荐文章于 2020-12-07 17:19:01 发布