2

模擬試験を使ってC++試験の勉強をしています。特定のコンストラクターがいつ呼び出されるかを判断する際に問題が発生します。コードは-

using namespace std;
#include <iostream>

class Fraction
{
  private:
   int numerator, denominator;
  public:
   Fraction( int = 0, int = 1 );
   friend ostream& operator<<( ostream&, const Fraction& );
  };

 void debug( Fraction, Fraction );
 Fraction task( Fraction&, const Fraction& );

int main()
  {
    Fraction * A[6], * B; // Line 1
    Fraction C( 3 ), D( C ); // Line 2
    Fraction E[4], F = D; // Line 3
    Fraction G, H( 3, 4 ); // Line 4
    debug( C, D ); // Line 5
    B = new Fraction; // Line 6
    F = task( H, C );
    delete B;
    return 0;
  }

 void debug( Fraction X, Fraction Y )
 {
   cout << X << endl << Y << endl;
 }

 Fraction task( Fraction& X, const Fraction& Y )
 {
   Fraction Z;
   Z = Fraction( 5, 2 ); // Line 7
   return 1; // Line 8
 }

さて、デフォルトのコピーコンストラクターは3種類のインスタンスで呼び出されると思いました。

例1-

        Fraction A(1,2);

        Fraction B(A);

例2-

        Fraction A(1,2);

        Fraction A = B;

3-関数からオブジェクトが返されたとき

4-オブジェクトがパラメータとして関数に渡されるとき

私が答えられないように思われる2つの質問があります-

質問1-上記のソースコードを検討してください。「3行目」および「4行目」というラベルの付いたステートメントがコンパイルおよび実行されると、これらのステートメントごとに、クラス「Fraction」のコンストラクターが何回呼び出されますか。

答えは-D)3行目:5回の呼び出し4行目:2回の呼び出し

この質問への答えはDです。しかし、私がそれに答えると、別の結果が得られます-

    Fraction E[4], F = D; // Line 3

配列E[4]に対してデフォルトのコンストラクターが5回呼び出されていることがわかりますが、このステートメントも-と同等であると思いました。

    Fraction E[4], Fraction F(D);

したがって、デフォルトのコンストラクターは5回呼び出され、コピーコンストラクターは1回呼び出されます。明らかに、これは正しくなく、コンストラクターは5回しか呼び出されないためです。エラーがどこにあるのかわかりません。

私の他の問題は次の質問にあります-

  1. 図2(前のページ)のソースコードについて考えてみます。「7行目」および「8行目」というラベルの付いたステートメントがコンパイルおよび実行されると、これらのステートメントごとに、クラス「Fraction」のコンストラクターが何回呼び出されますか。

    答えは-D)7行目:1回の呼び出し8行目:1回の呼び出し

        Fraction task( Fraction& X, const Fraction& Y )
        {
          Fraction Z;
          Z = Fraction( 5, 2 ); // Line 7
          return 1; // Line 8
        }
    

    私は当初、デフォルトのコンストラクターを呼び出してFraction(5,2)の一時オブジェクトを作成し、次にコピーコンストラクターがFraction(5、2)をZにコピーすると考えていました。これは実際にはデフォルトの代入演算子の操作ですか?8行目については、Fraction型のオブジェクトを返しているため、これはコピーコンストラクターを呼び出していますか?

私がここにいる間にもう少し質問があります-

だろう-

debug(B, C)

コピーコンストラクターを2回呼び出して、FractionオブジェクトBとCのコピーを渡しますか?

そして -

F = task( H, C );

デフォルトの代入演算子とFを呼び出すと、初期化されたFractionオブジェクトとしてすでに存在しますか?

4

1 に答える 1

1

基本的に、デフォルトのコンストラクターとコピーコンストラクターがいつ呼び出されるかを知りたいと思います。

あなたの最初の質問のために:

Fraction E[4], F = D; // Line 3

E[4]はオブジェクトの配列でありFraction、これらのオブジェクトを初期化するために他のコンストラクターを明示的に呼び出さなかったため、デフォルトのコンストラクターを4回呼び出します。2行目では、オブジェクトDはすでに構築されているためF、コピーコンストラクターを使用して構築されます。この場合、ユーザーが自分でオブジェクトを定義しなかったため、コンパイラーがオブジェクトを生成します。したがって、この場合、4つのデフォルトコンストラクター呼び出しと1つのコピーコンストラクター呼び出しがあります。4行目では、両方のオブジェクトがデフォルトコンストラクターを呼び出すため、デフォルトのctorで2回呼び出されます。

debug(B, C)
call the copy constructor twice to pass copies of Fraction objects B and C?

はい、パラメーターはdebug関数内の値によって渡されるため、コピーコンストラクターはBC

一般に、コピーコンストラクタは次の状況で呼び出されます。

  1. 1つのオブジェクトを既存のオブジェクト(asF= DまたはF(D))でインスタンス化する場合
  2. オブジェクトを値で渡す場合。
  3. オブジェクトが関数から値で返されるとき。

これにより、コードを理解するのに十分な情報が得られることを願っています。

于 2013-03-24T02:10:44.023 に答える