0

明日の朝、テストの準備をしています。私は以下のC++ウォークスルーに苦労しています。コードを実行し、coutを使用してプログラムの実行を確認しました。私が最初に気付いたのは、プログラムがクラス「one」のデフォルトのコンストラクターを、mainの最初のオブジェクトに対して3回呼び出していることです。私はコードの実行と本当に混乱しています。

    #include <iostream>
    using namespace std;

    class one {
    int n;
    int m;
      public:
    one() { n = 5; m = 6; cout << "one one made\n"; }
    one(int a, int b) {
      n = a;
      m = b;
      cout << "made one one\n";
    }
    friend ostream &operator<<(ostream &, one);
    };

    ostream &operator<<(ostream &os, one a) {
    return os << a.n << '/' << a.m << '=' <<
     (a.n/a.m) << '\n';
    }

    class two {
    one x;
    one y;
      public:
    two() { cout << "one two made\n"; }
    two(int a, int b, int c, int d) {
      x = one(a, b);
      y = one(c, d);
      cout << "made one two\n";
    }
    friend ostream &operator<<(ostream &, two);
    };

    ostream &operator<<(ostream &os, two a) {
    return os << a.x << a.y;
    }

    int main() {
    two t1, t2(4, 2, 8, 3);
    cout << t1 << t2;
    one t3(5, 10), t4;
    cout << t3 << t4;
    return 0;
    } 

私は最初のことを理解していません。mainが最初のデフォルトコンストラクターを呼び出すと、two t1,なぜ3回続けて呼び出されるのt2(4, 2, 8, 3);でしょうか?

コードが長すぎる場合は申し訳ありませんが、それを理解するには本当に助けが必要です。

お知らせ下さい。ありがとうございました。

4

4 に答える 4

4

コードを実行すると、次の結果が得られます。

one one made
one one made
one two made
one one made
one one made
made one one
made one one
made one two

それの訳は:

two t1;
one one made //t1.x; parameterless 'one' constructor called by default
one one made //t1.y; parameterless 'one' constructor called by default
one two made //t1; parameterless 'two' constructor

t2(4, 2, 8, 3)
one one made //t2.x; default constructor as variable not present in initialization list

one one made //t2.y; default constructor as variable not present in initialization list

made one one //x = one(a, b) executed now
made one one //y = one(c, d) executed now
made one two //t2(int..) constructer called

初期化リストがないため、t2の場合はxとyが2回作成されることに注意してください。これを回避するには、次を使用できます。

two(int a, int b, int c, int d): x(a,b), y(c,d)
{
cout << "made one two\n";
}
于 2012-04-10T05:21:25.720 に答える
2

両方のオブジェクトの3つのインスタンスが作成されるため、クラス「1」とクラス「2」の両方のコンストラクターが3回発生することがわかります。

インサーターフレンド関数を注意深く見ると、クラス1とクラス2は両方とも、参照ではなく値によって渡されます。一時インスタンスは、デフォルトのコピーコンストラクター(実装していない)を使用して作成する必要があります。余分なインスタンス化を廃止したい場合は、インサーター関数を次のように変更します。

friend ostream &operator<<(ostream &, one &obj); 
friend ostream &operator<<(ostream &, two &obj); 

さらに詳しく見てみると、2つにはタイプ1の2つのメンバー変数があるので、私が理解しているコンストラクターはさらに多くなります。

最後に、このようなテストクラスにはfooとbarという名前を付ける必要があります。1と2は自分でもコミュニケーションが難しい。(私見では)

于 2012-04-10T05:08:13.123 に答える
1

mainの最初のオブジェクトから。クラス「two」にはクラス「one」のオブジェクトが2つあり、通常どおり1つのデフォルトコンストラクターが「Two」と呼ばれるため、「one」の2つのデフォルトコンストラクターが呼び出されます。

于 2012-04-10T05:27:20.070 に答える
1

これが私が見るその出力です:

one one made
one one made
one two made
one one made
one one made
made one one
made one one
made one two
5/6=0
5/6=0
4/2=2
8/3=2
made one one
one one made
5/10=0
5/6=0

そして、それは私にとって完全に理にかなっています。最初のオブジェクトに対して3回呼び出されるデフォルトのコンストラクターが表示されません。

出力に関する限り、ここで何が起こりますか?

two t1, t2(4, 2, 8, 3);

t1の場合、クラスで定義されている両方のオブジェクトに対して、1つのデフォルトコンストラクターを呼び出します。

two (one x and one y)

したがって、出力は「one one made」であり、次に「one one made」であり、次に2のデフォルトコンストラクターを実行します。したがって、出力はt2に対して次の「onetwo made」であり、xとyの両方に対して1のデフォルトコンストラクターを再度呼び出します。次に実行されるのは「1つ作成」と「1つ作成」です

x = one(a,b) and y =one(c,d)

これで、two()のコンストラクターで「madeoneone」と「madeoneone」が出力されます。「madeonetwo」も同じように出力されます。

cout << t1 << t2;

one t3(5, 10), t4;

このステートメントでも、t3の場合は、oneのコンストラクターを呼び出して「madeone one」を出力し、t4の場合は、デフォルトのコンストラクターを実行して「oneonemade」を出力します。

cout << t3 << t4;
于 2012-04-10T05:31:39.600 に答える