1

私は誰かが私にこれに似た何かを実装することができるかもしれない方法を私に説明できるかどうか疑問に思いました:

namespace advanced_cpp_oop
{
  class A
  {
    B b;
  };

  class B : public A
  {
  };
}

int main()
{
}

基本クラスのインスタンスに派生クラスのインスタンスを含めることができるのはどこですか?上記のコードをコンパイルすると、次のエラーが生成されます。

g++ advanced_cpp_oop.cpp 
advanced_cpp_oop.cpp:8:5: error: ‘B’ does not name a type

コンパイルを行う(ほぼ)同等のJavaコードは次のとおりです。

public class AdvancedCppOop
{
  public static void main(String[] args)
  {
    A a;
  }
}

class A
{
  B b;
}

class B extends A
{
}

ありがとう

4

4 に答える 4

5

ポインターと前方宣言を追加する必要があります。

namespace advanced_cpp_oop
{
  class B;

  class A
  {
    B* b;
  };

  class B : public A
  {
  };
}

C ++コードでは、class B内部のインスタンスを作成していますがclass A、コンパイラはまだ何も(特にサイズを)認識していないため、これは不可能ですclass B

私の答えのコードを使用して、のインスタンスを動的に割り当て、コード内の別の場所class Bのポインターに割り当てる必要がありbます。

ちなみに、親クラスはサブクラスに依存してはならないため、設計の観点からは、これは実際には意味がありません。

于 2013-01-11T21:04:04.660 に答える
4

これは、unique_ptrなどのある種のポインターと前方宣言を使用して行う必要があります。

  class B;

  class A
  {
    std::unique_ptr<B> b;
  };

  class B : public A
  {
  };

これはばかげていますが、おそらくデザインを再考する必要があります。

于 2013-01-11T21:06:32.107 に答える
3

C++とJavaの間には非常に重要な違いが1つあります。C ++は値セマンティクスを備えた言語ですが、Javaは参照セマンティクスを備えた言語です。Javaでプリミティブ型以外の変数を作成する場合、その型のオブジェクトではなく、そのようなオブジェクトへの参照を作成します。それどころか、C ++では、同じ構造が実際のオブジェクトを参照します。

これを覚えておけば、次のことがうまくいかない理由を簡単に理解できます。

class Base {
   Derived d;
};
class Derived : Base {};

C ++の最初の定義は、オブジェクトBaseにDerived型のオブジェクトが内部的に(参照ではなく)含まれていることを意味します。同時に、Derivedには、継承によってBaseタイプのサブオブジェクトが含まれています。

つまり、Derivedには、Baseを含むDerivedを含むBaseが含まれています... BaseまたはDerivedのサイズはどのくらいですか?

参照セマンティクスを使用する言語、またはポインターを使用する場合はC ++では、これは問題ではありません。Baseオブジェクトには、Derivedへの参照/ポインタが含まれています。Derivedには、継承によるBaseサブオブジェクトが含まれています。Baseのサイズはよく知られています。他のすべてのフィールドに加えて、参照/ポインターのサイズです。Derivedのサイズは、Baseのサイズに、追加された追加のメンバーを加えたものです。

于 2013-01-11T22:21:20.770 に答える
2

アンドレアスは私を正解に打ち負かしましたが、Javaコードは、B b = new B(...);たとえそのように見えなくても、Javaオブジェクトがポインターによって暗黙的に保持されているため(したがって、ステートメントがJavaコード全体に散らばっているため)にのみ機能することを付け加えておきます。コンパイラはBオブジェクトの大きさを知らないため、元のC ++コードは機能しません(クラスBの前方宣言が追加されていても)。したがって、それを含むAオブジェクトの大きさもわかりません。一方、すべてのポインターは(指定されたタイプに関係なく)同じサイズであるため、BオブジェクトをクラスAのBオブジェクトへのポインターに置き換えても、コンパイラーはそのような問題を抱えていません。

于 2013-01-11T21:09:18.940 に答える