zoukankan      html  css  js  c++  java
  • C++拷贝构造函数被调用的时机

    拷贝构造函数调用的几种情况:

    • 当用类的一个对象去初始化该类的另一个对象(或引用)时系统自动调用拷贝构造函数实现拷贝赋值。
    • 若函数的形参为类对象,调用函数时,实参赋值给形参,系统自动调用拷贝构造函数。(这里可有可能被编译器优化)
    • 当函数的返回值是类对象时,系统自动调用拷贝构造函数。(注意会有编译器可能会进行优化,而观察不到拷贝的发生)

    举例说明:

    #include<ctime>
    #include<cstdlib>
    #include<iterator>
    #include<algorithm>
    #include<iostream>
    #include<numeric>
    using namespace std;
    
    class A {
    public:
    	A():data(0){}
    	A(const A& a){
    		data = a.data;
    		cout << "拷贝构造函数调用
    ";
    	}
    	A& operator=(const A&a){
    		data = a.data;
    		cout << "调用赋值函数
    ";
    		return *this;
    	}
    
    	int data;
    };
    
    void fun1(A a) {
    	return ;
    }
    
    A fun2() {
    	A a;
    	return a;
    }
    
    int main() {
    	A a;
    	A b(a);          //用类的一个对象a去初始化另一个对象b
    	A c = a;         //用类的一个对象a去初始化另一个对象c,注意这里是初始化,不是赋值
    	fun1(a);         //形参为类对象,实参初始化形参,调用拷贝构造函数。
    	A d = fun2();    //函数返回一个类对象时, 这里可能会被编译器优化,从而可能没有调用拷贝构造
    	d = a;           //d已经初始化过了,这里是赋值,调用赋值函数
    
    	return 0;
    }
    

    需要注意,在第三条:当函数的返回值是类对象时,系统自动调用拷贝构造函数。这里默认情况下一般会被编译器优化,减少不必要的拷贝构造,所以,具体的返回值可能会因编译器及编译选项的不同而不同。使用g++编译器,关闭优化g++ xxx.cpp -fno-elide-constructors后执行结果如下:

    拷贝构造函数调用
    拷贝构造函数调用
    拷贝构造函数调用
    拷贝构造函数调用
    拷贝构造函数调用
    调用赋值函数
    

    默认情况下,优化后的结果如下:

    拷贝构造函数调用
    拷贝构造函数调用
    拷贝构造函数调用
    调用赋值函数
    

    编译器具体是怎么优化的,一般编译器会先看支不支持拷贝优化,如果不支持,再看有没有定义移动构造函数,如果都没有,就调用拷贝构造函数。更具体的细节可以参考移动语义及拷贝优化的内容。

  • 相关阅读:
    Oracle结构连接配置结构
    理解cookie和session机制
    Asp.net中网站级异常捕获
    C#字符串函数大全
    一个简单的C#多线程间同步的例子
    SQL中的存储过程存放位置
    类和结构的区别?
    SQL点滴9—使用with语句来写一个稍微复杂sql语句
    Asp.NET 的Session实现原理 转自21kaiyun.com
    Script to analyze table space usage
  • 原文地址:https://www.cnblogs.com/s-lisheng/p/13049423.html
Copyright © 2011-2022 走看看