從建構函式或解構函式呼叫(純)虛擬成員

標準(10.4) 規定:

可以從抽象類的建構函式(或解構函式)呼叫成員函式; 對於從這樣的建構函式(或解構函式)建立(或銷燬)的物件,直接或間接地對純虛擬函式進行虛擬呼叫(10.3)的效​​果是未定義的。

更一般地說,一些 C++權威,例如 Scott Meyers,建議永遠不要從建構函式和 dstructors 呼叫虛擬函式(甚至是非純函式)。

請考慮以下示例,從以上鍊接修改:

class transaction
{
public:
    transaction(){ log_it(); }
    virtual void log_it() const = 0;
};

class sell_transaction : public transaction
{
public:
    virtual void log_it() const { /* Do something */ }
};

假設我們建立了一個 sell_transaction 物件:

sell_transaction s;

這隱式呼叫 sell_transaction 的建構函式,它首先呼叫 transaction 的建構函式。當呼叫 transaction 的建構函式時,該物件尚未屬於 sell_transaction 型別,而僅屬於 transaction 型別。

因此,transaction::transaction()log_it 的呼叫,不會做看似直覺的事情 - 即呼叫 sell_transaction::log_it

  • 如果 log_it 是純虛擬的,就像在此示例中一樣,行為是未定義的。

  • 如果 log_it 是非純虛擬的,則會呼叫 transaction::log_it