如果你設計了一個類別,它不適合被繼承使用,例如它沒有虛擬解構子 (virtual destructor)、沒有虛擬函式 (virtual function),也沒有 protected 函式,那麼請為它加上 final,這樣編譯器便可以阻止此類別被繼承。
class CString final
{
// ...
};
接下來考慮一種情況,如果有一個交易系統要寫 log,它使用通用的 log 類別,所有的函式都滿足需求,只有一個函式 (SendLog) 的功能不滿足,但好消息是此函式是虛擬函式可以被改寫,如下:
class CLog
{
public:
virtual ~CLog()
{}
public:
virtual void SendLog()
{}
};
因為兩者間不是 is-a 關係,而是 is-implemented-in-terms-of (根據某物實作出) 關係,因此我們選擇 private 繼承 CLog,並改寫 SendLog。
class CTradingSystem : private CLog
{
public:
virtual ~CTradingSystem()
{}
private:
virtual void SendLog() // 改寫 SendLog
{}
};
但我們可能希望 CTradingSystem 也可以被當作基底類別,又不想繼承的類別去改寫 SendLog,為了隱藏 SendLog,在 C++ 03 前我們可能會使用嵌套式的私有類別,並且由此類別去 public 繼承 CLog 並改寫 SendLog,如下:
class CTradingSystem
{
public:
virtual ~CTradingSystem()
{}
private:
class CTradingSystemLog : public CLog
{
public:
virtual ~CTradingSystemLog()
{}
public:
virtual void SendLog() // 改寫 SendLog
{}
};
private:
CTradingSystemLog m_log; // 這樣來使用 SendLog
};
好消息是,在 C++ 11 不用那麼麻煩了,你可以直接為不想被改寫的虛擬函式加上 final 解決這件事。
class CTradingSystem : private CLog
{
public:
virtual ~CTradingSystem()
{}
private:
virtual void SendLog() final // 阻止繼承的類別改寫
{}
};