是否可以创建可由配置控制的不同类?

时间:2009-07-06 10:54:27

标签: c++ constructor configurability

是否可以控制从配置中创建不同的类?

说,我有一个功能,它执行硬编码:

BaseClass* getClassObject(int type)
{
    switch (type)
    {
    case 1:
        return new DerivedClass1();
    case 2:
        return new DerivedClass2();
    default:
        return 0;
    }
}

是否可以将控件转移到某种数据结构,以便用户只需填写数据结构来控制函数的行为方式?

6 个答案:

答案 0 :(得分:2)

正如Neil在C ++中提到的,你不能在运行时发明类。

我可能没有理解你的问题,但是如果你想让一个函数/对象在用户提供的数据上表现不同,你可以根据需要尝试以下任何一个。

1]如您的代码段中所述,您可以使用开关或条件语句(以不同方式对用户提供的数据执行功能)

2]您可以使用Factory模式创建所需的对象类型(根据用户提供的数据创建不同的对象,此对象可以在代码中具有可替换的公共基类以生成不同的行为)

3]你可以使用组合    a)创作者功能,    b)继承和接口    c)和动态库加载 在运行时创建和加载适当类型的对象。  (这是根据给定的用户数据在运行时仅加载特定对象或函数)

答案 1 :(得分:1)

在C ++中,必须在编译时知道所有类型的名称。您不能允许用户在运行时创建类。您发布的函数将起作用 - 配置文件将包含一个整数,指示要创建DerivedClass1或DerivedClass2。这被读取并用于执行切换。

答案 2 :(得分:1)

您可能会觉得有用Factory method pattern

答案 3 :(得分:1)

根据问题中提供的有限信息,您可能需要考虑阅读和/或考虑使用C ++依赖注入容器。

这可能对您的要求有点重,但这个问题很难说清楚。仅供参考,依赖注入(http://martinfowler.com/articles/injection.html)是Martin Fowler创造的一个术语,是一种更具体的控制反转(我将让您进一步研究这两个主题)。

我个人使用过Castle Windsor,这是一个C#/。NET依赖注入容器,可以通过配置文件运行时构建所请求的对象。

维基百科上有一个C ++依赖注入容器列表(http://en.wikipedia.org/wiki/Dependency_injection#Existing_frameworks) - 自从我做了任何C ++以来已经有几年了,所以我不能告诉你更多关于它们的信息。

答案 4 :(得分:1)

另一种选择是使用原型模式,其中BaseClass的部分接口是clone()函数。然后创建一个原型实例数组,并在它们上调用clone来获取新对象。如果要创建值不同的实例以及仅在行为上有所不同的实例,这将非常有用,并且通常比创建工厂方法的工作少一些。

class BaseClass
{
public:
    virtual BaseClass* clone () const = 0;
    virtual ~BaseClass() { }
    virtual void write () const = 0;
};

template <class C>
class Cloneable : public BaseClass
{
public:
    virtual BaseClass* clone () const {
        return new C ( *static_cast<const C*> ( this ) );
    }
};

class TypeA : public Cloneable<TypeA>
{
    int value;

public:
    TypeA ( int value ) : value ( value ) { }

    virtual void write () const {
        std::cout << "TypeA ( " << value << " ) @ " << ( void* ) this << std::endl;
    }
};

class TypeB : public Cloneable<TypeB>
{
public:
    TypeB () { }

    virtual void write () const {
        std::cout << "TypeB @ " << ( void* ) this << std::endl;
    }
};



int main ( int argc, char* argv[] )
{
    std::vector<BaseClass*> prototypes;

    prototypes.push_back ( new TypeA ( 1 ) );
    prototypes.push_back ( new TypeA ( 2 ) );
    prototypes.push_back ( new TypeB );

    // create some objects
    std::vector<BaseClass*> instances;

    for ( size_t i ( 0 ); i < 8; ++i )
        instances.push_back ( prototypes [ i % 3 ] -> clone() );

    for ( size_t i ( 0 ); i < 8; ++i )
        instances[ i ] -> write();

    // todo: delete everything
}

答案 5 :(得分:0)

我不是C ++大师 - 我来自Delphi / C#背景。在Delphi或C#中,我使用反射来动态创建可能的类列表,然后选择在某个配置文件中配置的类。但是,我不确定这在C ++中是否可行?