首頁 >後端開發 >C++ >如何從類別名稱字串實例化 C 物件?

如何從類別名稱字串實例化 C 物件?

Susan Sarandon
Susan Sarandon原創
2024-12-18 00:25:10505瀏覽

How Can I Instantiate C   Objects from Class Name Strings?

從類別名稱字串實例化物件

在C 中,如果沒有明確映射,則無法從包含類別名稱的字符串實例化物件。此限制源自於 C 的靜態特性,其中類型必須在編譯時已知。

選項 1:使用範本手動對應

您可以建立範本函數對於要實例化的每個類別以及將類別名稱連結到對應範本函數的對應。例如:

template<typename T> Base* createInstance() { return new T; }

map_type map;
map["DerivedA"] = &createInstance<DerivedA>;
map["DerivedB"] = &createInstance<DerivedB>;

要實例化對象,請使用:

return map[some_string]();

選項2:運行時類型註冊

您可以擁有類別使用靜態機制註冊自身,然後動態檢索實例。這涉及使用單例映射來儲存類別名稱到函數的映射。以下是一個範例:

struct BaseFactory {
    static Base * createInstance(std::string const& s) {
        auto it = getMap()->find(s);
        return it != getMap()->end() ? it->second() : nullptr;
    }

    static std::map<std::string, std::function<Base*()>> * getMap() {
        if (!map) { map = new std::map<std::string, std::function<Base*()>>; }
        return map;
    }

private:
    static std::map<std::string, std::function<Base*()>> * map;
};

template<typename T>
struct DerivedRegister : BaseFactory {
    DerivedRegister(std::string const& s) {
        getMap()->insert({s, &createInstance<T>});
    }
};

class DerivedB {
private:
    static DerivedRegister<DerivedB> reg("DerivedB");
};

此方法允許在執行時自動註冊類別。

選項3:Boost Variant

如果您有沒有共同基類的不相關類,您可以使用Boost 變體庫:

typedef boost::variant<Foo, Bar, Baz> variant_type;
template<typename T> variant_type createInstance() { return variant_type(T()); }

typedef std::map<std::string, variant_type (*)()> map_type;

此技術允許從單一字串實例化不同類型。

總之,C 缺乏從類別名稱字串實例化物件的內建機制。但是,使用範本、運行時註冊或 Boost 變體庫,您可以實現類似的功能。

以上是如何從類別名稱字串實例化 C 物件?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn