C.82:Doがコンストラクタとデストラクタで仮想関数を呼び出しません
C.82は:コンストラクタまたはデストラクタで仮想関数を呼び出さないでください
理由(理由)
呼び出された関数ではなく、派生クラスでオーバーライド可能性の機能よりも、これまでに構築されたオブジェクトのものになります。これは、最も混乱することができます。さらに悪いことに、未定義の動作中に、コンストラクタやデストラクタ結果から実装されていない純粋仮想関数への直接または間接的な呼び出し。
これまでのところ、呼び出された関数は、カバーのみの機能の派生クラスで存在してもよいのではなく、オブジェクト自体を構築するために属している必要があります。理解することは非常に困難ですか。最悪の場合は、直接または間接的に、コンストラクタまたはデストラクタの呼び出しで、純粋仮想関数は、未定義の動作が発生します実装されていません。
例えば、悪い(陰性試料)
class Base {
public:
virtual void f() = 0; // not implemented
virtual void g(); // implemented with Base version
virtual void h(); // implemented with Base version
virtual ~Base(); // implemented with Base version
};
class Derived : public Base {
public:
void g() override; // provide Derived implementation
void h() final; // provide Derived implementation
Derived()
{
// BAD: attempt to call an unimplemented virtual function
f();
// BAD: will call Derived::g, not dispatch further virtually
g();
// GOOD: explicitly state intent to call only the visible version
Derived::g();
// ok, no qualification needed, h is final
h();
}
};
具体的な明示的に修飾された関数を呼び出すと、関数が仮想であっても、仮想呼び出しではないことに注意してください。
注:特定の関数を呼び出す関数が仮想関数の場合でも、仮想呼び出しを定義されていません。
未定義の動作を危険にさらすことなく、派生クラスの関数の呼び出しの効果を達成する方法については、工場出荷時の関数も参照してください。
参考植物は未定義の動作の原因となる危険性がなくても、関数を呼び出すために、派生クラスの効果を達成する方法を理解するために機能します。
Note(注意)
コンストラクタとデストラクタから仮想関数を呼び出すと、本質的には何も問題はありません。このような呼び出しのセマンティクスは型安全です。しかし、このような呼び出しはほとんど必要ありませんことを経験ショーは、簡単にメンテナを混同し、初心者が使用する際にエラーの原因になります。
コンストラクタから呼び出され、デストラクタ仮想関数自体は、すべてのエラーを持っていません。この呼び出しセマンティクスは安全です。しかし、経験は、このような呼び出しはほとんど必要であることが示されている、使用され、初心者には誤差の原因になることができれば、守備陣を混乱させることは容易です。
施行(提案)
-
旗は、コンストラクタとデストラクタから仮想関数を呼び出します。
-
コンストラクタまたはデストラクタの呼び出しからヒント仮想関数。
説明リンク
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c82-dont-call-virtual-functions-in-constructors-and-destructors
私はこの記事は参考になりましだと思いますか?ようこそ親指アップし、より多くの人と共有することができます。
より多くの更新の記事を読む、オブジェクト指向の考え方のマイクロチャンネル公衆数にしてください注意を払います[]