天天看點

C++核心準則C.82:不要在構造函數或析構函數中調用虛函數

C.82: Don't call virtual functions in constructors and destructors

C.82:不要在構造函數或析構函數中調用虛函數

Reason(原因)

The function called will be that of the object constructed so far, rather than a possibly overriding function in a derived class. This can be most confusing. Worse, a direct or indirect call to an unimplemented pure virtual function from a constructor or destructor results in undefined behavior.

到目前為止,被調用的函數應該隻屬于構造對象本身,而不是可能存在于派生類中的某個覆寫函數。那樣做非常難了解。最壞的情況,在構造函數或者析構函數中直接或間接調用一個沒有實作的純虛函數會導緻沒有定義的行為。

Example, bad(反面示例)

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 that calling a specific explicitly qualified function is not a virtual call even if the function is virtual.

注意:調用一個特定的限定函數不是虛調用,即使這個函數是虛函數。

See also factory functions for how to achieve the effect of a call to a derived class function without risking undefined behavior.

參考工廠函數以便了解如何達成調用派生類功能的效果而不必承擔引起未定義行為的風險。

Note(注意)

There is nothing inherently wrong with calling virtual functions from constructors and destructors. The semantics of such calls is type safe. However, experience shows that such calls are rarely needed, easily confuse maintainers, and become a source of errors when used by novices.

從構造函數和析構函數中調用虛函數并不是本身有什麼錯誤。這種調用的語義是安全的。然而,經驗表明這樣的調用很少是必須的,很容易擾亂維護者,如果被新手使用會成為錯誤源。

Enforcement(實施建議)

  • Flag calls of virtual functions from constructors and destructors.
  • 提示來自構造函數或析構函數的虛函數調用。

原文連結

​​https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c82-dont-call-virtual-functions-in-constructors-and-destructors​​

繼續閱讀