2011-11-25 13 views
5

Olası Çoğalt:
Is there a way to instantiate objects from a string holding their class name?Yalnızca bir ismini bilen bir nesneyi nasıl uygulayabilirim?

C++

, ben olsun dize bağlı olarak çalışma anında oluşturulacak benim kullanıcı nesne türü adı girin olmasını istiyoruz ve Onlardan, program doğru nesneyi başlatacaktır (kısaca, fabrika yöntemini uygulayacağım). Ancak, program yeni bir nesne türünü desteklemeli, mevcut kodu değiştirmeye izin verilmez.

Yani benim program, birçok dışında (belirli bir ürün türünün doğru nesnenin örneğini yönteminden tüm eğer ... else if ... else if ... şeyler kaldırmak ve hala sahip olmak mümkündür, sadece derleme zamanında bilinen)?

My arama

etrafında bana bu linki var: Is there a way to instantiate objects from a string holding their class name? ve buna istediğim bu gibi görünüyor ama ben hiç kod anlayamıyorum.

Herhangi bir yardım gerçekten takdir edilecektir.

+0

@CharlesB yansımasına ihtiyacınız yok, bir fabrika kullanabilirsiniz. –

+1

@LuchianGrigore: fabrika tasarım desenidir, yansıma bir dil özelliğidir. Eğer if..else..else olmadan çalışan bir fabrika istiyorsan ... – CharlesB

cevap

5

Bu yalnızca çalışacaktır, ve genel olarak çalışabilir olsa (baz arayüzü kullanarak sınırlı olacaktır:

Sen daha fazla bilgi için buraya başlayabilirsiniz bazı ek çaba ile etrafında).

// Immutable core code: 

#include <map> 
#include <string> 

class Base 
{ 
    typedef Base * (*crfnptr)(const std::string &); 
    typedef std::map<std::string, crfnptr> CreatorMap; 

    static CreatorMap creators; 

public: 
    virtual ~Base() { } 
    Base * clone() const { return new Base(*this); } 

    static Base * create_from_string(std::string name) 
    { 
    CreatorMap::const_iterator it = creators.find(name); 
    return it == creators.end() ? NULL : it->first(); 
    } 

    static void register(std::string name, crfnptr f) 
    { 
    creators[name] = f; 
    } 
}; 

Artık yeni koddan yeni türetilmiş sınıfları ekleyebilirsiniz::

// your code: 

#include "immutable_core.hpp" 

class Foo : public Base 
{ 
public: 
    Foo * clone() const { return new Foo(*this); } 
    static Foo * create() { return new Foo; } 
}; 

Base::register("Foo", &Foo::create); 

sadece Base * p = Base::create_from_string("Foo"); diyoruz, bir sınıf oluşturmak üzere İşte bir yaklaşımdır.

+0

'klon()' fonksiyonları burada ihtiyaç var Alessandro'nin yanıtında gibi yansıma olan bir dil veya bir ikili eklenti mimarisi, gerek? Onları çıkarmak için iyi bir fikir olup olmadığından emin değilim. – Daan

+0

@Daan: Haklısınız, fabrika için gerekli değiller, ancak bir nesnenin en türetilmiş tipini bilmediğiniz durumlarda kopya oluşturucunun rolünü alırlar, bu yüzden tematik olarak ilgili . –

+0

Eğer doğru bir şekilde anlarsam, onları Base * 'to' Derived * ''e benzetmeden görmeliyim. – Daan

2

Sen yapabileceği bir eklenti sistemi gibi bir şey uygulamak. Bunu Linux'ta dlopen ile uyguladım. Programın değiştirilmesine gerek yoktur, ancak yalnızca çalışma zamanında yüklenecek dinamik kitaplıklar olarak yeni sınıflar eklemeniz gerekir. Gerekli tüm sınıfları bazı ortak temel sınıftan türetilmiş ise C++ dlopen mini HOWTO

İlgili konular