web-dev-qa-db-ja.com

デフォルトのコンストラクタが必要になるのはいつですか?

私の質問は簡単です。デフォルトのコンストラクタが必要になるのはいつですか?以下のコードを参照してください:

class Shape
{
    int k;

public:
    Shape(int n) : k(n) {}
    ~Shape() {}
};

class Rect : public Shape
{
    int l;

public:
    Rect(int n): l(n)
    {}      //error C2512: 'Shape' : no appropriate default constructor available

    ~Rect() {}
};
  1. コンパイラーがクラスRectでゼロ引数のデフォルトコンストラクターを暗黙的に生成しないのはなぜですか?

  2. 私の知る限りでは、クラス(Rect)が(暗黙的に生成されるか明示的に提供される)デフォルトコンストラクターを持つ別のクラス(Shape)から派生する場合、デフォルトコンストラクターはコンパイラーによって生成される必要があります。

27
XMarshall

引数付きの独自のコンストラクターを作成した場合、デフォルトのコンストラクターは合成されません。 Shapeに独自のコンストラクターを指定したので、ここでデフォルトのShapeコンストラクターを明示的に書き込む必要があります。

_class Shape
{
      int k;

  public:
      Shape() : k(0) {}
      Shape(int n) : k(n) {}
      ~Shape() {}
};
_

(これらは合成されるため、空の~Rect() {}定義は省略できます。)

ただし、ここではShapeのデフォルトコンストラクターをwantしないように見えます。 RectShapeベースを適切に構築してもらいます:

_class Shape
{
      int area; // I've had to guess at what this member means. What is "k"?!

  public:
      Shape(const int area)
         : area(area)
      {}
};

class Rect : public Shape
{
     int l;
     int w;

  public:
     Rect(const int l, const int w)
        : Shape(l*w)
        , l(l)
        , w(w)
     {}
};
_

また、この例は OOの乱用として引用されることが多い であることにも注意してください。ここで継承本当に継承が必要かどうかを検討してください。

デフォルトのコンストラクターは、他のコンストラクターが定義されていない場合にのみ、コンパイラーによって自動的に生成されます。継承に関係なく。

また、次を呼び出して基本クラスを構築する必要もあります。

Rect( int n ) : Shape( n ), l(n)
{
}
11
Nick

コンパイラーが明示的な宣言を行わない場合にのみ、デフォルトのctorを定義します。

重要なのはdeclaringコンストラクタであり、必ずしもそれを定義しているわけではないことに注意してください。たとえば、プライベートActorを宣言し、それを決して定義せずに、コンパイラーが他のActorを暗黙的に定義しないようにすることはかなり一般的です。

編集:C++ 11には=defaultあなたのような状況に対処するための構文。

2
Jerry Coffin

C++ WRTコンストラクターの完全な動作については、これを参照してください。 http://en.wikipedia.org/wiki/Default_constructor

簡単な答えは、コンストラクターを指定した場合、コンパイラーがデフォルトのコンストラクターを作成しないことです。

このルールはJavaにも適用されます。

2
Mike Thomsen

デフォルトのコンストラクタは、他のコンストラクタを定義していない場合にのみ生成されます。

おそらく、クラスで特別な初期化が必要な場合、デフォルトのコンストラクターは正しく動作しません。

0
Bo Persson

整数を期待するShapeのコンストラクタを定義したので、そうすることでデフォルトのコンストラクタを上書きしました。したがって、Shapeを拡張する場合は、整数値をスーパークラスに渡す必要があります。

0
das_weezul

コンストラクタを定義していない場合、コンパイラはデフォルトのコンストラクタを生成します。ただし、引数を取るかどうかに関係なくコンストラクタを定義した場合は、コンパイラーはそのコンストラクターを使用し、引数がゼロのデフォルトのコンストラクターを生成しません。

0
Sarfraz Ahmed