0

不足しているデフォルトのコンストラクタエラーをスローし続ける複雑なプログラムがあり、多くのことをいじくり回した後、同じエラーが発生するまったく同じシナリオを見つけました。これの何が問題なのですか?

class B;

class A
{
public:
    A() {instance = new B;}
    virtual ~A() {delete instance;}
private:
    A*instance;
};

class B : public A
{
public:
    B(){}
}

基本クラス内で使用される派生クラスを前方宣言できませんか?

4

4 に答える 4

2

new Bコンパイラがまだクラスについて何も知らない場合、どうすれば成功するBでしょうか? メンバー関数の実装を classAの定義の下のクラスから移動するBと、動作するはずです。

class A
{
public:
    A();
    virtual ~A();
private:
    A * instance;
};

class B : public A
{
public:
    B(){}
};

A::A()
{
    instance = new B;
}

A::~A()
{
    delete instance;
}

とにかく、AとBは正確には何ですか?基本クラスで派生クラスをインスタンス化することは、少し珍しいことです。

于 2012-07-21T15:59:27.460 に答える
0

B の定義の後に、A のコンストラクターの定義 (ただし、宣言ではない) を A の外側に配置する必要があります。完全な (完全に定義された) 必要がない限り、A で B を使用することは問題ありませんnew B。 .

于 2012-07-21T15:59:53.180 に答える
0

コンパイラがどのように先を見据えるかに関する c++ の規則は明らかではありません (たとえばinstance、メンバーがクラスの後半で定義されている場合でも、メソッドで使用することは問題ありませんが、同じソース ファイルで後で定義されているクラスを使用することは問題です)。 .

この場合の問題は、(他のレポートのように) コンパイル時new Bにコンパイラがクラスである以上のことを知っている必要があり、実際に何であるかを確認するBためにクラスを超えて読み続けないことです。AB

考えられる解決策の 1 つは、コンストラクターとデストラクターの定義A後で配置することです (インラインのままにしておきます)。

class B;

class A
{
public:
    A();
    virtual ~A();
private:
    A *instance;
};

class B : public A
{
public:
    B() {}
};

inline A::A() { instance = new B; }
inline A::~A() { delete instance; }

これはコンパイルされますが、実際にここでやろうとしていることはかなり混乱しているため、正しく実行されません。

のインスタンスを作成するには、Aのインスタンスを作成しますがB、これBは の特殊化であるAため、 のインスタンスを作成すると、 ( の基本サブオブジェクト)のBインスタンスも作成されます。AA B

これは、 のインスタンスを作成するには、 のインスタンスをA間接的に作成する必要があることを意味しますA

ばかげているようですね。

このコードでのインスタンスA(または のB) をインスタンス化すると、無限の再帰が発生します (つまり、ほとんどの実装で異常なクラッシュが発生します)。

于 2012-07-21T16:09:16.237 に答える
-1

いいえ。派生クラスには追加の要素が含まれている可能性があるためです。したがって、それを使用して基本クラス オブジェクトを派生クラス オブジェクトで初期化することはできません。

于 2012-07-21T16:00:39.010 に答える