あなたは、戻り値の最適化と呼ばれる体験(What are copy elision and return value optimization?を参照してください)。
コンパイラはコードを最適化し(オブジェクトの作成を最小限に抑えるため)、オペレータによって宣言され返されたローカルオブジェクトをa
にします。次に、コピーコンストラクタは使用されません。これはあなたがここで観察するものです。うまくオブジェクトのメモリは住所が見るためにあなたのコードを変更し、これを観察する
:
#include <iostream>
using namespace std;
class MyClass
{
public:
MyClass()
{
cout << "default constructor has been called for " << std::hex << this << endl;
}
MyClass(const MyClass& cls)
{
cout << "copy constructor has been called for " << std::hex << this << " (copied from " << &cls << ")" << endl;
}
MyClass operator+(const MyClass& cls) const
{
cout << "operator + has been called!" << endl;
MyClass res;
cout << "operator + returns temporary object " << std::hex << &res << endl;
return res;
}
MyClass& operator=(const MyClass& cls)
{
cout << "operator = has been called!" << endl;
return *this;
}
};
int main()
{
MyClass b, c;
MyClass a = b + c;
cout << "a object is " << std::hex << &a << endl;
return 0;
}
それは出力:
あなたは
operator+
で作成した一時オブジェクトは
a
(
0x7ffd44b769ff
と同じであることがわかり
default constructor has been called for 0x7ffd44b769fd
default constructor has been called for 0x7ffd44b769fe
operator + has been called!
default constructor has been called for 0x7ffd44b769ff
operator + returns temporary object 0x7ffd44b769ff
a object is 0x7ffd44b769ff
を)、コンパイラの最適化のためです。
g ++を使用する場合、このコンパイラの最適化を無効にするには、-fno-elide-constructors
でコンパイルしてください。そして、出力は以下のようになります。
は
default constructor has been called for 0x7ffd92847d1c
default constructor has been called for 0x7ffd92847d1d
operator + has been called!
default constructor has been called for 0x7ffd92847cff
operator + returns temporary object 0x7ffd92847cff
copy constructor has been called for 0x7ffd92847d1f (copied from 0x7ffd92847cff)
copy constructor has been called for 0x7ffd92847d1e (copied from 0x7ffd92847d1f)
a object is 0x7ffd92847d1e
あなたは今operator+
は最終的に構築するために使用された後に、return文のための一時的なオブジェクトとしてコピーされるローカルオブジェクト(0x7ffd92847cff
)、(0x7ffd92847d1f
から0x7ffd92847cff
をコピー)を作成していることがわかりaコピー(コピー0x7ffd92847d1f
〜0x7ffd92847d1e
)。
'MyClass&operator =(const MyClass&cls)' - この関数は、値を返さなかったため未定義の動作を呼び出します。 – PaulMcKenzie
私の間違い申し訳ありません。私はそれを修正しました。しかし、私はこの質問で深刻な誤解を招くとは思わない。 – AK2806
プログラムがどのように機能するかは、それが重要なことです。戻り値はなく、何かが起こる可能性があります。 – PaulMcKenzie