1
#include <iostream>
#include <cstring>
using namespace std;

class foo {
     int number;
     char string[20];
public:
     foo( ) { 
          set(3, 5); 
     }
     void set (int a, int b) { 
          number = a + b;
        strcpy( string, "summer" ); 
     }

     foo (const foo & c ) { 
     }

     void output() { 
          cout << number << ',' << string << endl;  
     }
};

void showyanothing (foo);

int main() {
     foo a, b;
     showyanothing( a );
     a.output();
     b.output();
}

void showyanothing (foo z) { 
     cout << "... how are you?\n";
     z.output(); 
}

出力

... hello ...
... how are you?
-1218897013,l·ôl·Y·ôl·À
8,summer
8,summer

の行は-1218897013,l·ôl·Y·ôl·À、コピーコンストラクターによって作成されたオブジェクトZの値です。コピーコンストラクターを次のように変更すると、オブジェクトzを出力すると。が生成され10, summer.1.2.3ます。なんで?値はどこから魔法のようにZに挿入されましたか?

新しいコピーコンストラクタ

 foo (const foo & c ) { 
     number = c.number + 2;
     strcpy( string, c.string );
     strcat( string, ".1.2.3" );
 }

新しい出力:

... how are you?
10,summer.1.2.3
8,summer
8,summer

コピーコンストラクターで私が混乱しているのは、c.numberが8に等しく、c.stringが夏に等しいのはなぜですか?それらの値はどこから取得したのですか?

4

3 に答える 3

4

関数呼び出しを簡単にチェックしてください

void showyanothing (foo z) 

ここでコピーコンストラクタが呼び出されます。以前のコードにはコピーコンストラクターがあり、データメンバーの初期化が行われていないため、ランダムなvalが出力されます。一方、コピーコンストラクターを編集すると、結果が得られます(つまり、次のように呼び出されます)。

foo (const foo & c ) { 
     number = c.number + 2;
     strcpy( string, c.string );
     strcat( string, ".1.2.3" );
 }

それがあなたの疑問を解決することを願っています:)

于 2013-03-11T03:48:58.740 に答える
0

コピーコンストラクターの最初のバージョンは、fooのメンバー変数を初期化しません。したがってnumberstringランダムデータが含まれます-新しいオブジェクトがインスタンス化される場所のRAMにたまたまあったものは何でも。

2番目のバージョンは、参照によって渡されるオブジェクト(「コピー」と想定されるオブジェクト)に基づいて、メンバー変数に値を正しく割り当てます。この場合、デフォルトのコンストラクターを使用してインスタンス化されたa(を呼び出すためshowyanothing(a))を渡します。これにより、番号8と文字列"summer"が与えられます。

于 2013-03-11T03:50:06.827 に答える
0

オブジェクトは、初期化するかどうかに関係なく、メモリを占有します。メモリには任意の値が含まれています。初期化しない場合は、何でもかまいません。それはあなたが得る最初のガベージ出力を説明しています。

次に、渡されたソースオブジェクトに基づいてオブジェクトを初期化する実用的なコピーコンストラクターを提供します。最初に、デフォルトのコンストラクターを使用して構築されたmain()オブジェクトを作成します。したがって、呼び出しの結果、そのメンバーは8に設定されます。関数は、値によって渡されるパラメーターを取得します。つまり、オブジェクトを受け取るコピーコンストラクターを使用してクラスの新しいインスタンスを作成し、 's (8)に2を追加して、をコピーします。anumberset(3,5)showyanothing (foo z)fooaanumberstring

于 2013-03-11T03:52:45.367 に答える