0

重複の可能性:
派生クラスでオーバーライドされた関数が、基本クラスの他のオーバーロードを非表示にするのはなぜですか?

やあ、

この例で私の質問を説明しましょう:

class A
{
    virtual ~A() = 0 { }

    A(const A&);
    virtual void operator =(const A&) = 0;
}

class B : public A
{
    ~B();

    B(const B&);
    void operator =(const B&);
}

void main(void)
{
    A* a = new B();
    delete a; // Is ~A() called, ~B() or both ?
}

これにより、2つの質問をすることができます。

  1. abstract-base-classポインタでdeleteを使用すると、どのデストラクタが呼び出されますか?
  2. 上記のコピー方法のいずれかを使用して、オブジェクト「a」のコピーを作成することはできますか?
4

4 に答える 4

2
  1. 両方とも呼ばれます。

    delete a派生クラスでは、仮想ディスパッチメカニズムを使用してデストラクタが~B::B検出され、呼び出されます。次に、の実装は~B::B、基本クラスのデストラクタを暗黙的に呼び出します~A::A。ただし、この呼び出しは非仮想の通常の呼び出しとして実装されます。つまり~A::A、純粋であると宣言されているという事実の影響を受けません。

    これが、純粋な仮想デストラクタを定義する必要がある理由です。言語仕様では、純粋仮想関数のクラス内定義は許可されていませんが。インラインにしたい場合でも、クラス外で定義する必要があります。

  2. A抽象型のスタンドアロンオブジェクトが存在できないという理由だけで、型のスタンドアロンオブジェクトをコピーすることはできません。質問を明確にしてください。何をどこにコピーしたいですか?

    このようなことをしたい場合

    B b1, b2;
    A *a1 = &b1, *a2 = &b2;
    
    *a1 = *a2;
    

    そして、最後の割り当てが実行されたかのように動作することを期待しb1 = b2ます...まあ、それは実行できますが、ある程度の努力が必要であり、かなり醜いコードになる可能性があります。オーバーロードされた代入演算子にそのような機能を負わせるのは良い考えではないと思います。

于 2012-07-18T20:01:59.387 に答える
0
virtual ~A() = 0 { }

これはコンパイルされません。純粋な仮想デストラクタは次のようになります。

virtual ~A() = 0;

それでも、オブジェクトを破棄するときにクラス階層のすべてのデストラクターが呼び出されるため、実装追加する必要があります。したがって、本体を実装しない場合、これによりUBが発生します(または、gcc 4.6.3ではコンパイルされないためコンパイルされません)。

于 2012-07-18T19:28:14.633 に答える
0

1:~B()仮想を介して呼び出されます~A() = 0; 次に、の実装は~A()によって呼び出され~B()ます。

また、virtual ~A() = 0 { }構文が正しくありません。クラス定義の外部で記述virtual ~A() = 0;してから提供する必要があります。inline A::~A() { }

B::operator=(const B&)2 :;のオーバーライドとして受け入れられないため、コードはコンパイルされませんA::operator=(const A&) = 0。仮想メソッドに対して共変であることが許可されているのは、関数の戻り型のみです。

コピーコンストラクタまたは代入演算子を使用してポリモーフィックオブジェクトをコピーする簡単な方法はありません。そのようなメンバーはダブルディスパッチを使用する必要があるためです(仮想代入演算子C ++を参照)。通常のメソッドは、派生クラスvirtual A *clone() = 0のインスタンスを返すことが期待される関数を持つことです。new

于 2012-07-18T19:29:52.397 に答える
0

1)デストラクタ〜B()が最初に呼び出され、デストラクタ〜A()の後に、次のことを覚えておいてください。

コンストラクターが呼び出された場合、デストラクタは逆の順序で呼び出されます。

2)はい、それはポインターであるため、遺産はコピーをブロックする可能性があります(再コピーによるコンストラクター)

于 2012-07-18T19:59:09.550 に答える