首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC++

C++ 實現不可繼承類別 (Final Class) 的技巧

     編輯:VC++

問題背景

Java 有 final 關鍵字禁止類別被繼承,C++ 無內建機制。需求場景:控制繼承層級、防止菱形繼承、API 設計約束。核心思路:阻止子類別建構基底類別部分,使其無法實例化。

方案演進

嘗試 1:私有建構函式 + 靜態工廠

class Base {
private:
    Base() {}
public:
    static Base* Create() { return new Base(); }
};
缺點:語法笨拙,使用者必須記得呼叫 Create(),且無法自然支援繼承鏈。

嘗試 2:利用 Friend 不可繼承特性 (失敗)

class FinalMixin {
    friend class Derived; // 僅 Derived 可存取
private:
    FinalMixin() {}
    ~FinalMixin() {}
};

class Derived : public FinalMixin { /* ... */ };

class Further : public Derived { /* 編譯通過!原因:Further 透過 Derived 建構 FinalMixin */ };
失敗原因:Further 雖非 Friend,但透過 Derived 的建構函式間接完成 FinalMixin 建構,繞過存取檢查。

最終解法:虛繼承 + 私有建構 + 模板化

關鍵洞察:虛基類別的建構函式由最末端衍生類別直接呼叫。若 FinalMixin 建構函式為私有,且僅授權 Derived 為 Friend,則 Further 必須直接呼叫 FinalMixin() 而失敗。

template 
class FinalMixin {
    friend T; // 僅授權具體衍生類別
private:
    FinalMixin() {}
    ~FinalMixin() {}
};

// 使用方式
class MyBase { /* ... */ };

class MyFinalClass : virtual public FinalMixin, public MyBase {
public:
    MyFinalClass() {}
    ~MyFinalClass() {}
};

// 測試
class TryDerive : public MyFinalClass {}; // 編譯錯誤:無法存取 FinalMixin 建構函式

int main() {
    MyFinalClass ok;   // 正常
    // TryDerive fail; // 編譯錯誤
    return 0;
}

關鍵點總結

  • virtual 繼承強制最末端類別建構虛基類。
  • friend T 模板化,免去每次修改 Friend 宣告。
  • FinalMixin 為純類別 (無資料成員),無菱形繼承資料冗餘與二義性風險。
  • 不適用於純靜態類別 (無建構需求),但這類設計通常值得反省。

延伸應用:Mixin 模式

此技術屬於 Mixin (混入) 模式一種,同理可實作 NonCopyable、Singleton 等編譯期約束。多重繼承非洪水猛獸,關鍵在於使用者的設計功力。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved