• 构造函数和析构函数在函数调用过程中的调用情况


    一个有趣的类

    我在这个类中定义了构造,拷贝构造,移动构造,拷贝运算符,移动运算符,析构,这几种特殊函数。这个类可以观察调用对象时的操作实现。

    class Test {
    public:
    	Test(string x):str(x){
    		cout << "Constructor " << str << endl;
    	}
    	Test(const Test& x) :str(x.str) {
    		cout << "Copy Constructor " << x.str << endl;
    
    	}
    	Test(Test&& x) :str(x.str) {
    		cout << "Move Constructor " << x.str << endl;
    	}
    
    	Test& operator=(const Test& x) {
    		cout << "Copy-Assignment Operator " << str << endl;
    		str = x.str;
    		return *this;
    	}
    	Test& operator=(Test&& x) {
    		cout << "Move-Assignment Operator " << str << endl;
    		str = move(x.str);
    		return *this;
    	}
    	~Test() {
    		cout << "Destructor " << str << endl;
    	}
    
        void address(){
    		cout << "address " << this << endl;
        }
    	string  str;
    };
    
    

    使用代码

    使用该类查看函数参数和返回值的内部实现

    Test f(Test c) {
    	cout << "---func start---" << endl;
    	Test a("a"), b("b");
    
    	cout << "---func end---" << endl;
    
    	return a;
    }
    int main() {
    	cout << "---start---" << endl;
    	Test c("c");
    	cout << "---entry---" << endl;
    	Test a=f(c);
    	cout << "---break---" << endl;
    	Test b = a;
    	b = a;
    	cout << "---end---" << endl;
    	return 0;
    }
    
    

    输出

    以下是该代码在不同编译器下的输出,建议配合着源代码和分割线观看并理解。

    可以看出Microsoft C/C++ 编译器是较符合预期的,没有进行太多的优化。

    test_Microsoft C/C++ :
    
    ---main start---
    Constructor c               Test c("c");
    ---entry---
    Copy Constructor c          Test tf(Test c) 拷贝构造参数c。
    ---func start---
    Constructor a               Test a("a"), b("b");
    Constructor b               构造两个对象a、b。
    ---func end---
    Move Constructor a          Test a=tf(c) 将函数内对象a移动到main中对象a。
    Destructor b                离开函数,析构局部变量,
    Destructor a                这里可以看出会先返回值后,再将变量析构。
    Destructor c
    ---break---
    Copy Constructor a          Test b = a 虽然使用的是“=”但还是调用拷贝构造
    Copy-Assignment Operator a  b = a 正常调用拷贝运算符
    ---main end---
    Destructor a                离开main函数析构对象
    Destructor a
    Destructor c
    
    
    

    g++ 优化了一部分内容,另外通过调用该类的 address 方法,你会发现 main 函数中的 a 对象和调用函数中的 a 对象的地址相同。

    test_g++ :
    
    ---main start---
    Constructor c
    ---entry---
    Copy Constructor c
    ---func start---
    Constructor a
    Constructor b
    ---func end---                  其他部分都和上面相同,但这里少了个移动操作。
    Destructor b
    Destructor c                    这里少了给析构a的操作。
    ---break---                     实际上是将a的对象地址直接给了main中的a,甚至没调用移动构造
    Copy Constructor a
    Copy-Assignment Operator a
    ---main end---
    Destructor a
    Destructor a
    Destructor c
    
    
    
  • 相关阅读:
    php环境搭建工具包推荐
    Android视频直播解决方案(rstp、udp)
    软件版本号命名
    附加数据库失败,无法升级数据库,因为它是只读的
    Web Api如何传递POST请求
    找回Reshaprer的Alt+Enter快捷键的方法
    asp.net 实现在线打印功能,jQuery打印插件PrintArea实现自动分页
    asp.net 回发或回调参数无效的各种情况分析及解决办法
    MQTT, XMPP, WebSockets还是AMQP?泛谈实时通信协议选型 good
    echarts 专题
  • 原文地址:https://www.cnblogs.com/komet/p/16289805.html
Copyright © 2020-2023  润新知