Rumah >pembangunan bahagian belakang >C++ >Bagaimanakah Saya Boleh Menghidupkan Objek C daripada Rentetan Nama Kelas?

Bagaimanakah Saya Boleh Menghidupkan Objek C daripada Rentetan Nama Kelas?

Susan Sarandon
Susan Sarandonasal
2024-12-18 00:25:10563semak imbas

How Can I Instantiate C   Objects from Class Name Strings?

Pemasangan Objek daripada Rentetan Nama Kelas

Dalam C , tidak mungkin untuk membuat instantiat objek daripada rentetan yang mengandungi nama kelas tanpa pemetaan eksplisit . Had ini berpunca daripada sifat statik C , di mana jenis mesti diketahui pada masa penyusunan.

Pilihan 1: Pemetaan Manual Menggunakan Templat

Anda boleh mencipta fungsi templat untuk setiap kelas yang anda ingin nyatakan dan peta untuk memautkan nama kelas kepada fungsi templat yang sepadan. Contohnya:

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

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

Untuk membuat instantiate objek, gunakan:

return map[some_string]();

Pilihan 2: Pendaftaran Jenis Runtime

Anda boleh mempunyai kelas daftarkan diri mereka dengan mekanisme statik dan kemudian dapatkan semula kejadian secara dinamik. Ini melibatkan penggunaan peta tunggal untuk menyimpan nama kelas kepada pemetaan berfungsi. Berikut ialah contoh:

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");
};

Kaedah ini membenarkan pendaftaran kelas secara automatik pada masa jalan.

Pilihan 3: Varian Boost

Jika anda mempunyai kelas yang tidak berkaitan tanpa kelas asas biasa, anda boleh menggunakan perpustakaan varian 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;

Teknik ini membolehkan untuk instantiasi pelbagai jenis daripada rentetan tunggal.

Kesimpulannya, C tidak mempunyai mekanisme terbina dalam untuk instantiasi objek daripada rentetan nama kelas. Walau bagaimanapun, menggunakan templat, pendaftaran masa jalan atau pustaka varian Boost, anda boleh mencapai kefungsian yang serupa.

Atas ialah kandungan terperinci Bagaimanakah Saya Boleh Menghidupkan Objek C daripada Rentetan Nama Kelas?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn