Rumah > pembangunan bahagian belakang > C++ > Bagaimana untuk Mencipta Objek C daripada Rentetan yang Mengandungi Nama Kelasnya?

Bagaimana untuk Mencipta Objek C daripada Rentetan yang Mengandungi Nama Kelasnya?

Patricia Arquette
Lepaskan: 2024-12-20 01:33:10
asal
1070 orang telah melayarinya

How to Create C   Objects from a String Containing Their Class Name?

Bagaimana untuk Mengkonfigurasi Objek daripada Rentetan yang Mengandungi Nama Kelasnya?

Dalam kod yang diberikan, kelas BaseFactory mencipta objek daripada kelas Terbitan yang berbeza berdasarkan rentetan yang mewakili nama kelas mereka. Walau bagaimanapun, kilang memerlukan penambahan manual pernyataan if untuk setiap kelas Terbitan yang mungkin. Seseorang mungkin tertanya-tanya sama ada terdapat alternatif kepada pendekatan verbose ini, serupa dengan ciri Reflection C#.

malangnya tiada mekanisme automatik

Malangnya, C tidak mempunyai mekanisme untuk objek ciptaan automatik jenis yang ditentukan pada masa jalan. Walau bagaimanapun, pemetaan boleh dilakukan sendiri:

Pemetaan jenis

Anda boleh mencipta peta yang menyimpan, untuk setiap nama kelas, fungsi yang mencipta objek daripada kelas itu:

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

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

map_type map;
map["DerivedA"] = &amp;createInstance<DerivedA>;
map["DerivedB"] = &amp;createInstance<DerivedB>;
Salin selepas log masuk

Kemudian anda boleh membuat instantiate objek juga bantuan:

return map[some_string]();
Salin selepas log masuk

Taip pendaftaran

Penyelesaian alternatif ialah membenarkan jenis mendaftar sendiri:

// w base.hpp:
template<typename T> Base * createT() { return new T; }

struct BaseFactory {
    typedef std::map<std::string, Base*(*)()> map_type;

    static Base * createInstance(std::string const&amp; s) {
        map_type::iterator it = getMap()->find(s);
        if(it == getMap()->end())
            return 0;
        return it->second();
    }

protected:
    static map_type * getMap() {
        // nigdy nie usuwane (istnieje do zakończenia programu)
        // ponieważ nie możemy zagwarantować poprawnej kolejności usuwania
        if(!map) { map = new map_type; }
        return map;
    }

private:
    static map_type * map;
};

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

// w derivedb.hpp
class DerivedB {
    ...;
private:
    static DerivedRegister<DerivedB> reg;
};

// w derivedb.cpp:
DerivedRegister<DerivedB> DerivedB::reg("DerivedB");
Salin selepas log masuk

Anda juga boleh menentukan makro untuk pendaftaran jenis :

#define REGISTER_DEC_TYPE(NAME) \
    static DerivedRegister<NAME> reg

#define REGISTER_DEF_TYPE(NAME) \
    DerivedRegister<NAME> NAME::reg(#NAME)
Salin selepas log masuk

Untuk jenis yang tidak berkongsi kelas asas biasa, anda boleh menggunakan varian boost::variant sebagai jenis pemulangan fungsi:

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;
Salin selepas log masuk

Atas ialah kandungan terperinci Bagaimana untuk Mencipta Objek C daripada Rentetan yang Mengandungi Nama Kelasnya?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
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
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan