2017-01-27 12 views
-2

C++では、関数を実際に実装せずにヘッダファイルに関数を完全に宣言することができます。これは正常にコンパイルされ、通常これは問題を提供しません...私は、仮想デストラクタが実装されていないときに問題を引き起こす可能性がありますか?仮想デストラクタは宣言されていても実装されていないとどうなりますか?

仮想デストラクタが実装されておらず、その場合、派生クラスのインスタンスを基本クラスのポインタで削除すると、引き続き派生クラスのデストラクタが呼び出されますか?

など。

class Base{ 
public: 
    virtual ~Base() {} 
}; 

class Derived: public Base { 
public: 
    ~Derived(); // HAS NO IMPLEMENTATION 
}; 

Base *b = new Derived(); 
delete b; 

注:上記の例では正しく表示されていません。より多くの洞察を得ようとしている状況を説明するためにここで提供されていますが、リンク処理中に実際にはundefined reference to Derivedというエラーが発生します。

+0

_In C++では、関数を実際に実装せずにヘッダファイルに完全に宣言することができます。これはうまくコンパイルされ、通常、これは何の問題もありません。そうしないと、リンカエラーが発生します。それはあなたの例のようです。 –

+0

このコメントは、私がコードに行った更新をたどっただけで、実装されるBaseのデストラクタを変更し、Derivedのデストラクタが実装されていないことに注意してください。 – Gio

+2

実際に**あなたのコードを試しましたか?例えば、 'Derived ::〜Derived() ''への未定義参照のようなリンカエラーが発生します。 –

答えて

4

仮想デストラクタは宣言されても実装されていないとどうなりますか?

デストラクタが(あなたの例のように)呼び出された場合、プログラムは1つの定義ルールに違反するため、不正な形になります。標準では診断は不要であり、コンパイラーは間違っていることを伝えることができません。しかし、幸運にもリンカのエラーでおそらく保存されるでしょう。

C++では、関数を実際に実装せずにヘッダファイルに完全に宣言できます。

これは当てはまります。しかし、私たちはそのような機能を呼び出すことはできません。


仮想デストラクタが質問に非常に関連していません。これらのルールはすべての機能に適用されます。

+0

実際にODRに違反していますか? ODRには、「変数、関数、クラスタイプ、列挙型、またはテンプレートの複数の定義を1つの翻訳単位に含めることはできません」*という意味です。*定義が1を超える場合、ODRは違反します。 0の定義がある場合、それは違反されているODRではありません。 –

+2

@ChristianHackl ODRセクションはかなり大きく、最初のパラグラフに限定されません:) * "すべてのプログラムは、そのプログラム内でodr-used であるすべての非インライン関数または変数の**正確に1つの定義**を含みます;診断が必要です。」* – user2079303

+0

真。それはパラグラフ4です。ODRは、正式に定義が存在することを基本的に必要とするものではありませんでした。 –

6

~Derived()bを削除するなど)を呼び出すと、デストラクタのシンボルが存在しないため、リンクエラーが発生します。 ~Base()は仮想なので、bを削除すると、~Derived()が呼び出されます(試行されます)。実装の欠如はそれに関係していません。

+0

鮮明に見て、その情報で質問を更新しました。 – Gio

関連する問題