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

C++ 通過基類註冊表調用兄弟類實例:跨層級協作模式

     編輯:C++ 入門

問題場景

類 B 和 C 繼承自基類 A。C 需要調用 B 的方法,但不想直接持有 B 的指針(耦合、生命週期管理困難)。解決方案:在基類 A 中維護一個靜態註冊表,所有子類實例構造時自動註冊,析構時注銷。C 通過遍歷註冊表查找 B 類型實例並調用。

核心設計

  1. 基類 A 定義靜態數組 ChildrenNode Children[N],存儲 void* 指針 和 類型枚舉
  2. 提供靜態方法 addChildren(void*, NodeType)、delChildren(index)、getChildren(index)
  3. 子類 B 構造時 addChildren(this, T_B),析構時 delChildren(index)
  4. 子類 C 調用 getChildren() 遍歷,根據類型 static_cast<B*>(ptr) 調用 B 方法
  5. 完整代碼

    
    // A.h
    #ifndef A_H
    #define A_H
    enum NodeType { T_A=0, T_B=1, T_C=2, T_Count };
    struct ChildrenNode { void* p; int type; };
    class A {
    public:
        A(); ~A();
        static int addChildren(void* child, NodeType type);
        static void delChildren(int index);
        static const ChildrenNode* getChildren(int index);
        static const int N = 10;
    private:
        static ChildrenNode Children[N];
    };
    #endif
    
    // A.cpp
    #include "A.h"
    ChildrenNode A::Children[N] = {};
    A::A() {} A::~A() {}
    int A::addChildren(void* child, NodeType type) {
        if (!child || type >= T_Count) return -1;
        for (int i=0;i=0 && index=0&&index
    B::B() { sum = addChildren(this, T_B); }
    B::~B() { delChildren(sum); }
    void B::PrintSum() { printf("B: %d\n", sum); }
    
    // C.h
    #include "A.h"
    class C : public A {
    public:
        C(); ~C();
        void PrintAllBsum();
    };
    
    // C.cpp
    #include "C.h"
    #include "B.h"
    C::C() {} C::~C() {}
    void C::PrintAllBsum() {
        for (int i=0;ip && node->type == T_B) {
                static_cast(node->p)->PrintSum();
            }
        }
    }
    
    // main.cpp
    #include "B.h"
    #include "C.h"
    #include 
    int main() {
        C c;
        B* bs[10];
        for (int i=0;i<10;++i) {
            bs[i] = new B();
            sleep(1);
            c.PrintAllBsum(); // 動態發現並調用所有 B 實例
        }
        for (int i=0;i<10;++i) delete bs[i];
        return 0;
    }
    

    運行效果

    B: 0
    B: 0
    B: 1
    B: 0
    B: 1
    B: 2
    ...
    

    每次新建 B,C 都能立即發現並調用其方法。

    優缺點分析

    改進方向

    • 用 std::vector 替換固定數組,支持動態擴容
    • 引入 typeid 或 std::type_index 實現類型安全查找
    • 提取註冊表為獨立 Registry 類,基類僅提供介面
    • 結合觀察者模式:B 變更時通知 C,而非輪詢

    總結

    基類註冊表模式是 C++ 中實現「兄弟類互調」的經典技巧。通過靜態容器管理子類實例指針,配合類型標識實現動態發現與調用。雖有一定侵入性,但在插件系統、組件框架、模塊解耦場景中極具價值。現代 C++ 可結合智能指針、類型擦除、觀察者模式進一步增強健壯性。

    1. 上一篇文章:
    2. 下一篇文章:
    Copyright © 程式碼之家 All Rights Reserved
    優點缺點
    解耦:C 不依賴 B 具體定義,僅依賴基類註冊機制靜態數組容量固定(N=10),需預估最大實例數
    動態發現:運行時創建/銷毀 B 實例自動生效類型轉換用 static_cast,需確保類型匹配(可用 dynamic_cast 配合 RTTI)
    無需傳遞指針:適合插件架構、模塊化系統基類膨脹:註冊邏輯污染基類職責