2012-01-11 10 views
0

以下のコードを与えると、Aのデストラクタがプライベートであるというエラーが表示されるのはなぜですか?明らかにそれはプライベートですが、このようにBのAオブジェクトインスタンスを初期化すると、Aのデストラクタが呼び出される理由がわかりません。オブジェクトの初期化中にデストラクタコール?

私は、ネットワーク接続されていないシステムからメモリからコードを再作成しており、コンパイラを持っていません。

class A 
{ 
    public: 
     A(int val) : x(val) {} 

    private: 
     int x; 
     ~A() {} 
}; 

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

    private: 
     A aInstance; 
}; 

int main() 
{ 
    B b; 
} 
+0

スタックベースのオブジェクトでは(間接的にも)実行できません。プライベートデストラクタの使用方法や制限については、こちらをご覧ください:http://stackoverflow.com/questions/631783/what-is-the-use- of-destruction-as-private – holtavolt

答えて

5

がデストラクタを使用して関与していませんが、Bのインスタンスがmainの終わりに破壊され、それ自体の初期化エラーを取得するために、ここでAデストラクタへの暗黙的な呼び出しがあります。 BにはAが含まれているので、Bが破壊された場合、Aも破棄する必要がありますが、Aのdtorは使用できないため、そのコードを生成することはできません。

2

Bクラスは(プライベートフィールドaInstanceなど)Aクラスのインスタンスが含まれているので、それはBのインスタンスが破棄されるときに破壊されなければなりません。

これはまさにあなたのmainの内部で起こることです。 B b;はスタックに割り当てられて作成されるため、関数が終了すると範囲外になり、C++のすべてのローカルオブジェクトと同様に破棄する必要があります。

0

main()の最後に、Bが範囲外になると、BはどのようにしてA型のメンバの割り当てを解除するのですか?

デストラクタをprivateに宣言したため、できません。

+0

これは、Bの問題を抱えているメインではありません。コンパイラは自動的にAを削除する必要があるデストラクタを作成します。Aのデストラクタへのアクセスはありません。 – CashCow

+0

不明な先行が修正されました。 – nsanders

0

Aは、Bのメンバーです。タイプBのデフォルト生成コンストラクタは、それぞれのフィールドのデストラクタをルール呼び出しする必要があります。したがって、それはアクセス権を持っていないとあなたが

0

Aのデストラクタがコンストラクタ内から呼び出されているとは限りません。 Aへのデストラクタは、bがmain(プログラムが終了するとき)のスコープから外れるときに呼び出されている可能性があります。

0

実際にはmain()ではなくデストラクタにアクセスする必要があります。

BさんをAの友人にすると、うまくいきます。 main()をAの友人にすると、コンパイルされません。

Aのインスタンスが「自動」、つまりクラスメンバーであると宣言されているため、その削除はBのデストラクタでは発生しませんが、Bの削除中に行われます。しかしながら、これはクラスとしてのBのアクセスの範囲内にあると考えられる。

関連する問題