6

コンストラクターが呼び出されていないように見える状況があります。

#include <iostream>

using namespace std;

int main ()
{
    class yoyo
    {
        public:
        int i;
        yoyo()
        {
            i = 0;
            cout << "defaultly initialized to 0" << endl;
        }
        yoyo (int j) : i(j)
        {
            cout << "initialized to " << j << endl;
        }
    };

    int i;

    yoyo a;
    cout << "Hello1, i: " << a.i << endl;

    yoyo b(5);
    cout << "Hello2, i: " << b.i << endl;

    yoyo c = b;                                   /* 1 */
    cout << "Hello3, i: " << c.i << endl;

    return 0;
}

出力は次のとおりです。

defaultly initialized to 0
Hello1, i: 0
initialized to 5
Hello2, i: 5
Hello3, i: 5

(注: Hello2 と Hello3 の間には何もありません)

プログラムを次のように変更すると、次のようになります。

#include <iostream>

using namespace std;

int main ()
{
    class yoyo
    {
        public:
        int i;
        yoyo()
        {
            i = 0;
            cout << "defaultly initialized to 0" << endl;
        }
        yoyo (int j) : i(j)
        {
            cout << "initialized to " << j << endl;
        }
    };

    int i;

    yoyo a;
    cout << "Hello1, i: " << a.i << endl;

    yoyo b(5);
    cout << "Hello2, i: " << b.i << endl;

    yoyo c; c = b;                                  /* 1 */
    cout << "Hello3, i: " << c.i << endl;

    return 0;
}

(唯一の違いは、/* 1 */ でマークされた行にあります)

出力は次のとおりです。

defaultly initialized to 0
Hello1, i: 0
initialized to 5
Hello2, i: 5
defaultly initialized to 0
Hello3, i: 5

ここで、Hello2 と Hello3 の間にコンストラクター呼び出しがあります。私の質問は、最初のケースで (目に見える) コンストラクター呼び出しがないのはなぜですか?

4

4 に答える 4

16

の場合

yoyo c = b;

呼び出されるのはコピー コンストラクターです。

そして、の場合

yoyo c; c = b;

呼び出されるのはコピー代入演算子です。

それらのいずれも提供しない場合、コンパイラはデフォルトのバージョンを生成します。


独自のコピー コンストラクターを作成する場合は、次のようになります。

yoyo(const yoyo& other)
    : i(other.i)
    { std::cout << "copy constructor initialized\n"; }

コピー代入演算子は次のようになります。

yoyo& operator=(const yoyo& other)
    {
        i = other.i;
        return *this;
    }

もちろん、どちらもクラス定義内で定義されています。

于 2013-06-25T00:57:17.650 に答える
7

最初のケースでは:

yoyo c = b;   

copy constructorこの場合、コンパイラが暗黙的に生成する を呼び出します。

于 2013-06-25T00:57:37.720 に答える
3
 yoyo c = b; 

これは、コピー初期化と呼ばれます。コンパイラによって生成されたコピー コンストラクターが呼び出され、cそのコピーで初期化されます。また、デフォルトのコンストラクターcが呼び出されます。

c = b;

ここで、これは初期化ではなく、代入です。コンパイラによって生成された代入演算子は、その行で呼び出されます。

于 2013-06-25T00:58:21.013 に答える
1

あなたのコードで、

yoyo c=bコピーコンストラクターを呼び出します。それが呼び出されていることを確認したい場合は、明示的に定義する必要があります。

例えば:

yoyo(const yoyo& obj)
{
   this->i=obj.i;  cout<<"copy constructor"<<endl;
}

2 番目のケースでは、コンストラクターを呼び出し、次に代入演算子を呼び出します。

yoyo c; //constructor
c = b;  //assignment operator for which only copying occurs

以下のように代入演算子をオーバーロードできます

yoyo& operator=(yoyo& obj)
{
    i = obj.i;
    cout << "assignment operator" << endl;
}
于 2014-07-13T11:13:32.580 に答える