c++ 拷贝控制需要注意的几点

  1. 十三章 拷贝控制

  • 类的默认合成拷贝构造函数会拷贝数组成员。

  • 拷贝构造的发生条件及优化

    1. 实参传递给非引用类型形参

      class A(B)
      
    2. 函数返回类型为非引用类型并返回一个对象。 注意编译器可能会使用ROV(Return Value Optimization)优化,导致并没有发生拷贝构造.

      1. 返回值优化(RVO),即通过将返回值所占空间的分配地点从被调用端转移至调用端的手段来避免拷贝操作。返回值优化包括具名返回值优化(NRVO)与无名返回值优化(URVO),两者的区别在于返回值是具名的局部变量还是无名的临时对象

      2. RVO发生的条件:

        1. return 的值类型与 函数声明的返回值类型相同
        2. 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优化,未发生拷贝  
        }
        
    3. 类对象使用=初始化时。

      B b(2);
      B b1 = b;// 拷贝构造
      

      ​ 注意若右值是临时变量导致 右值拷贝优化

      1. 右值拷贝优化:即当类类型的临时对象=初始化同类型的对象时,通过直接利用该临时对象的方法来避免拷贝操作。
        这项优化只能用于右值(临时对象),不能用于左值

        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;
        }
        
    4. 花括号列表初始化元素为类类型的数组。

    5. 因为以上条件下都可能发生隐士初始化,所以一般不对拷贝初始化做explicit
      
  • 标准库要求保存在容器中的类型都要有拷贝赋值运算符 T& operator=(const T& ),否则会使用默认的合成拷贝赋值运算符。

  • 类内成员默认初始化在构造函数体之前完成,默认析构在析构函数体之后开始。

  • 类默认构造(包括拷贝)无法完成对const或引用成员的初始化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值