更多 C++ 慣用法/最終類
外觀
- 部分模擬 C++11 和其他語言中的 final 類特性。
- 部分阻止類進一步子類化或繼承。
- 密封類
類設計者可能希望強制執行特定類不能被類使用者進一步擴充套件或子類化。其他面向物件的語言,如 Java 和 C#,為類設計者提供了此功能。在 Java 中,關鍵字稱為 final,而在 C# 中,它稱為 sealed。最終類慣用法是在 C++ 中部分模擬此效果的一種方法。
最終類慣用法利用虛擬繼承和友元類來建立 final 類的效果。該慣用法依賴於以下 C++ 規則:虛擬繼承類的建構函式(和解構函式)由最派生類直接呼叫。如果阻止訪問此類虛擬繼承類的建構函式或解構函式,則該類不能進一步子類化。
class MakeFinal
{
MakeFinal() {} // private by default.
friend class sealed;
};
class sealed : virtual MakeFinal
{ };
class test : public sealed
{ };
int main (void)
{
test t; // Compilation error here.
}
在上面的示例中,test 類繼承自 sealed 類,main 函式嘗試例項化 test 型別的物件。例項化失敗,因為 test 類無法訪問 MakeFinal 類的私有建構函式,因為它被定義為私有並被虛擬繼承。但是,友誼不可繼承,因此無法建立 test 型別的物件。
請注意,該錯誤僅在例項化 test 類時才會發生。此行為與 Java 和 C# 中最終類行為不同。事實上,此慣用法不會阻止繼承 sealed 類中定義的靜態方法。只要 test 類未例項化,並且它僅訪問 sealed 類的靜態成員,編譯器就不會報錯。
C++11 標準提供了 final 修飾符,它可以用於阻止類被子類化。
class Base final { };
class test : public Base { }; // incorrect