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

C++ 類工廠模式實現動態對象創建 - 註冊機制與反射應用

     編輯:關於C++

問題背景

C++ 無內建反射機制,無法直接通過類名字符串創建對象。類工廠模式通過註冊表將類名映射到構造函數,實現運行時動態創建。

核心組件設計

1. 函數指針類型與工廠類

// 通用構造函數指針類型
using CreateFunc = void* (*)();

class DynObjectFactory {
    // 類名 -> 構造函數映射表
    static map registry;
public:
    // 註冊類
    static void Register(const string& name, CreateFunc func) {
        registry[name] = func;
    }
    // 通過類名創建對象
    static void* CreateObject(const string& name) {
        auto it = registry.find(name);
        return (it != registry.end()) ? it->second() : nullptr;
    }
};

// 靜態成員定義(selectany 避免多重定義)
__declspec(selectany) map DynObjectFactory::registry;

2. 自動註冊輔助類

class RegisterHelper {
public:
    RegisterHelper(const string& name, CreateFunc func) {
        DynObjectFactory::Register(name, func);
    }
};

3. 便利宏:一鍵完成靜態註冊

#define REGISTER_CLASS(class_name) \
    class class_name##Registrar { \
    public: \
        static void* CreateInstance() { return new class_name; } \
    private: \
        static RegisterHelper registrar; \
    }; \
    RegisterHelper class_name##Registrar::registrar(#class_name, class_name##Registrar::CreateInstance)

完整使用範例

基類介面

class Shape {
public:
    virtual void Draw() = 0;
    virtual ~Shape() {}
};

派生類實現與註冊

class Circle : public Shape {
public:
    void Draw() override { cout << "Circle::Draw()" << endl; }
    ~Circle() { cout << "~Circle" << endl; }
};
REGISTER_CLASS(Circle);

class Square : public Shape {
public:
    void Draw() override { cout << "Square::Draw()" << endl; }
    ~Square() { cout << "~Square" << endl; }
};
REGISTER_CLASS(Square);

class Rectangle : public Shape {
public:
    void Draw() override { cout << "Rectangle::Draw()" << endl; }
    ~Rectangle() { cout << "~Rectangle" << endl; }
};
REGISTER_CLASS(Rectangle);

主程序:動態創建與多態調用

void DrawAll(const vector& shapes) {
    for (auto* s : shapes) s->Draw();
}
void DeleteAll(const vector& shapes) {
    for (auto* s : shapes) delete s;
}

int main() {
    vector shapes;
    
    // 通過字符串動態創建
    shapes.push_back(static_cast(DynObjectFactory::CreateObject("Circle")));
    shapes.push_back(static_cast(DynObjectFactory::CreateObject("Square")));
    shapes.push_back(static_cast(DynObjectFactory::CreateObject("Rectangle")));
    
    DrawAll(shapes);
    DeleteAll(shapes);
    return 0;
}

運行結果

Circle::Draw()
Square::Draw()
Rectangle::Draw()
~Circle
~Square
~Rectangle

關鍵技術點解析

  1. 靜態註冊:RegisterHelper 全局對象構造時自動註冊,無需手動調用
  2. 宏生成唯一類名:class_name##Registrar 避免多類註冊衝突
  3. selectany 屬性:MSVC 擴展,允許頭文件中定義靜態成員(跨平台需改用內聯變量或單獨編譯單元)
  4. 虛析構函數:基類必須有虛析構,確保正確銷毀派生對象

擴展方向

  • 支援構造函數參數:使用 std::function + std::any 或變參模板
  • 插件系統:動態庫加載時自動註冊(dlopen/LoadLibrary)
  • 序列化/反序列化:配合 JSON 實現配置驅動的對象創建
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved