2015-12-20 11 views
16

私は次のように宣言されている抽象クラスがあります。仮想デストラクタをデフォルトにする必要がありますか?

class my_type { 
public: 
    virtual ~my_type() = default; 
    virtual void do_something() = 0; 
}; 

は、それがdefaultキーワードで、このようなデストラクタを宣言するために良い習慣を考えられますか?より良い方法がありますか?

また、= 0は、デフォルトの実装を指定しない現代的な方法(C++ 11)であるか、より良い方法がありますか?

+0

'virtual〜foo(){}'の何が問題なのですか? –

+0

私はちょうどC + + 11の方法は、デフォルトのキーワードを使用することだと思って..それはない? –

+3

@Humam 'virtual'と' data'の戻り値の型が間違っていることに注意してください。 – LogicStuff

答えて

17

はい、このようなデストラクタには、間違いなく= defaultを使用できます。特に、それを{}に置き換えるだけだったら。私は= defaultがより明白なのでより良いと思うので、すぐに目をつかんで疑いの余地はありません。

しかし、ここではそうする際に考慮すべき注意点がいくつかあります。

あなた= defaultヘッダファイルでデストラクタ(編集を参照)(またはそのことについては、他の特殊機能)、それは基本的にヘッダにそれを定義です。共有ライブラリを設計するときは、デストラクタをヘッダーではなくライブラリのみで明示的に指定して、従属バイナリの再構築を必要とせずに後で簡単に変更することができます。しかし、それは質問= defaultまたは{}のいずれかであるかどうかを単にではない場合のためです。


EDIT:ショーンが鋭くコメントで述べたように、あなたもここで両方の長所を取得するクラス宣言の= default外を使用することができます。


他の重要な技術的な違いは、標準を生成することができません明示的不履行機能は、単純に生成されないことを述べているということです。次の例を考えてみましょう:

struct A { ~A() = delete; }; 
struct B : A { ~B() {}; } 

これはないコンパイルだろう、あなたが指定したコードを生成するコンパイラを強制的に(そして、このようなAのデストラクタの呼び出しとその暗黙の前提条件、)Bのデストラクタのためにしているので、 - それAのデストラクタが削除されているため、できません。しかし、このことを考えてみましょう:

​​

これは、コンパイラは~B()が発生することができないことを見ているので、それは単にそれを生成しないので、実際には、、コンパイルう - と、削除されたとして、それを宣言します。これは、実際に/ B::~B()を使用/呼び出ししようとしているときにのみエラーが発生することを意味します。

これは、あなたが知っておくべき少なくとも2つの意味がありますから、あなたはクラス宣言が含まれて何かをコンパイルするときに、単にエラーを取得するために探しているなら、あなたはそれを得ることはありません

  1. をそれは技術的に有効です。
  2. 最初にそのようなデストラクタには常に= defaultを使用すると、スーパークラスのデストラクタが削除されていることを心配する必要はありません。エキゾチックな使い方ですが、それはもっと正確で将来的なものです。実際にデストラクタを使用する場合にのみ、エラーが発生します。そうしないと、一人で放置されます。

防御的なプログラミングアプローチを検討している場合は、単に{}を使用することを検討してください。そうでない場合は、= defaultを使用する方がよいでしょう。これは、正しいコードベースを取得し、意図しない結果を避けるために必要な最小限のプログラム命令を忠実に守るためです。。


について= 0については、はい、これは正しい方法です。しかし、実際には「デフォルトの実装はありません」とは指定されていませんが、(1)クラスはインスタンス化できません。 (2)任意の派生クラスはその関数をオーバーライドする必要があります(ただし、スーパークラスが提供するオプションの実装を使用できます)。つまり、関数を定義して純粋な仮想として宣言することができます。ここに例があります:

struct A { virtual ~A() = 0; } 
A::~A() = default; 

これは、A(およびそのデストラクタ)に対するこれらの制約を保証します。


1)、これは予想外の方法に有用であることができる理由の良い例が、一部の人々は常にC++ 14は、本質的に使用して間の技術の違いを作成したdecltype(auto)を追加し、その後に括弧でreturnを使用し、そしてどのようにそれはかっこ付きでもなくてもよい。

+1

私は通常、5/0_の_Ruleごとに "_big 5_"全体を 'デフォルト'します。そして、ちょうど情報のために:あなたが何らかの理由でデストラクタを純粋仮想にしたいのであれば、まだそれを実装する必要があります。 –

+3

"デストラクタ(またはそのような特別な関数)をデフォルトにしない場合は、その定義がヘッダファイルにないことを確認したいときです" - '= default '初期クラス定義の外にある関数定義についても同様です。私は些細な破壊性に気を使わず、リンカーの圧力を減らしたいと思うような場合には、特にそうしています。 –

+0

ありがとう@SeanMiddleditch。編集されました。 –

関連する問題