Bolehkah Objek Dimulakan daripada Rentetan Nama Kelas dalam C ?
Adakah terdapat mekanisme dalam C untuk membuat instantiate objek daripada rentetan yang mewakili nama kelasnya , menghapuskan keperluan untuk mentakrifkan pernyataan if-else secara eksplisit untuk setiap kelas terbitan berpotensi dalam kilang kelas?
Masalah:
Pertimbangkan struktur kelas berikut:
class Base; class DerivedA : public Base; class DerivedB : public Base; // etc...
Dan kelas kilang yang sepadan, BaseFactory, yang mencipta contoh terbitan kelas berdasarkan rentetan nama kelas yang ditentukan:
class BaseFactory { public: BaseFactory(std::string &sClassName) { msClassName = sClassName; }; Base * Create() { if(msClassName == "DerivedA") { return new DerivedA(); } else if(msClassName == "DerivedB") { return new DerivedB(); } // etc... }; private: string msClassName; };
Walau bagaimanapun, pendekatan ini memerlukan menyatakan secara eksplisit setiap kelas terbitan dalam BaseFactory, yang boleh menjadi menyusahkan apabila bilangan kelas terbitan bertambah.
Penyelesaian:
Tidak seperti dalam bahasa seperti C#, C tidak semestinya menyediakan mekanisme untuk mencipta objek secara dinamik berdasarkan maklumat jenis masa jalan. Untuk mencapai kefungsian yang serupa, seseorang boleh mempertimbangkan untuk membina pemetaan antara nama kelas dan fungsi penciptaan objek:
template<typename T> Base * createInstance() { return new T; } typedef std::map<std::string, Base*(*)()> map_type; map_type map; map["DerivedA"] = &createInstance<DerivedA>; map["DerivedB"] = &createInstance<DerivedB>;
Menggunakan peta ini, instantiasi objek menjadi:
return map[some_string]();
Sebagai alternatif, seseorang boleh mendaftar memperoleh kelas secara automatik semasa pemulaan program:
template<typename T> struct DerivedRegister : BaseFactory { DerivedRegister(std::string const& s) { getMap()->insert(std::make_pair(s, &createT<T>)); } }; // in derivedb.hpp class DerivedB { ...; private: static DerivedRegister<DerivedB> reg; }; // in derivedb.cpp: DerivedRegister<DerivedB> DerivedB::reg("DerivedB");
Pendekatan ini menghapuskan keperluan untuk pendaftaran kelas manual, kerana ia berlaku secara automatik apabila kelas ditakrifkan.
Ringkasan:
Walaupun C tidak secara langsung menyokong instantiasi objek daripada rentetan nama kelas, teknik ini menyediakan cara untuk mencapai kefungsian yang serupa dengan memetakan nama kelas kepada fungsi penciptaan objek atau dengan mengautomasikan proses pendaftaran.
Atas ialah kandungan terperinci Bolehkah C Menghidupkan Objek daripada Rentetan Nama Kelas?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!