c++ - 函数返回临时对象时有没有调用拷贝构造函数?
黄舟
黄舟 2017-04-17 14:45:37
0
3
674

函数返回临时对象时,有没有进行拷贝?会不会调用拷贝构造函数?
以下两段代码的区别只是一个显式定义了拷贝构造函数,一个没有定义,MSVC2013编译后运行的结果不同。但是可以从结果中看出,第一个并没有调用拷贝构造函数,到底是什么导致两者不同的结果呢?

代码一:

#include <iostream>

class A{
public:
    A(){ std::cout << this << " created" << std::endl; }
    ~A(){ std::cout << this << " destroied" << std::endl; }
    A(const A& a){ std::cout << "copy " << &a << " to " << this << std::endl; }// here is the difference
    void fn(){ std::cout << this << " call fn" << std::endl; }
};

A fn()
{
    A a;
    return a;
}

int main()
{
    A& a = fn();
    a.fn();
    return 0;
}

实际运行结果:

0079FC7B created
0079FC7B call fn
0079FC7B destroied

代码二:

#include <iostream>

class A{
public:
    A(){ std::cout << this << " created" << std::endl; }
    ~A(){ std::cout << this << " destroied" << std::endl; }
    void fn(){ std::cout << this << " call fn" << std::endl; }
};

A fn()
{
    A a;
    return a;
}

int main()
{
    A& a = fn();
    a.fn();
    return 0;
}

实际运行结果:

00EFF94B created
00EFF94B destroied
00EFF967 call fn
00EFF967 destroied

已找到没有调用拷贝构造函数的可能原因:使用Release方式进行编译的

黄舟
黄舟

人生最曼妙的风景,竟是内心的淡定与从容!

全員に返信(3)
PHPzhong

まず、g++ を使用してコードをコンパイルできません。A& a = fn(); この文はエラーを報告します: 'A&' 型の非定数を型の右辺値で初期化しています。 'A' 無効な参照です。

参照 (A a = fn();) を削除した後、コピー コンストラクターがまだ呼び出されないことがわかりました。オンラインで調べたところ、これは「コピー省略」と呼ばれていることがわかりました。これは、コピー コンストラクターに副作用がある場合でも、コンパイラーによって最適化されて取り除かれることを意味します。

いいねを押す +0
Peter_Zhu

最適化オプションをオンにしなくても、通常は最適化されます。
これは、欠陥のあるものを保持することが正しい選択である理由です。

いいねを押す +0
巴扎黑

C++11 の移動コピー コンストラクターについては、この回答を参照してください

いいねを押す +0
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート