使用 final 明確表達不想被繼承或改寫的意圖

如果你設計了一個類別,它不適合被繼承使用,例如它沒有虛擬解構子 (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 // 阻止繼承的類別改寫
	{}
};


留言