2017-02-01 18 views
4

は、次のコードを検討してください。今度はクラス内のクラスを関数内で宣言する必要がある2番目のコードを考えてみましょう。純粋仮想デストラクタは

void foo() 
{ 
    struct A { 
     virtual void foo() {} 
     virtual ~A() = 0; 
    }; 
    struct B :public A 
    { 
     virtual void foo() {}; 
    }; 
    A::~A() {}; //error C2352 : 'A::~A' : illegal call of non - static member function 

    A * a = new B(); 
    a->foo(); 
} 
int main() 
{ 
    foo(); 
} 

コードはコンパイルされません!何か案が?ローカルで宣言されている基本クラスの純粋な仮想デストラクタを再定義する方法はありますか?

+2

ローカルクラスのすべてのメソッド定義は、クラス内にインライン化する必要があります。 – Jarod42

+0

ローカルスコープにいるので(依存関係を制御するため)、 '= 0'を取り除いて直接コードを提供することができます。 – Jarod42

答えて

6

cppreferenceは、クラス宣言が現れること(...)と、ローカルクラス

を定義する場合、関数の本体、...

部材の内部

言いますローカルクラスの関数をクラス本体の中に完全に定義する必要があります。

4

希望する方法はありません。しかし、これも考慮してください:純粋な仮想デストラクタのボディ定義を与えるのはなぜですか?典型的な答えは、クラスを抽象的にしたいが、純粋な仮想にすることのできる他のメソッドはないということです。これが発生するシナリオは、通常、クラスの使用または継承を直接制御することができない場所です。しかし、これは関数内でローカルに定義されたクラスでは決して起こり得ません。定義によるその使用は全く同じ関数本体内になければなりません。したがって、たとえば、ローカル関数の直接制御されたコンテキスト内でこのルールを自分自身で観察するだけで、クラスをそのまま継承する(つまり、クラスを抽象にするという目的)を継承することができます。

1

C++ではネストされた関数を使用できません。 IMO

foo(){ 
//... 
A::~A{} // you define a nested function which is not allowed 
//... 
} 

を行うことにより、機能を持つネストされたクラスのために、私たちはクラスのブロック内のすべての非純粋関数を定義する必要があります。

クラスAを抽象クラスにしたい場合は、A :: foo()を純粋仮想クラスまたは新しい空の関数として宣言できます。いずれにしても、クラス外またはクラス内の仮想dtorを定義する必要があるため、リンクエラーが発生します。

関連する問題