2013-03-07 77 views
3

我有3个班BCD,从一个基类A得出:厂功能 - 如何做到这一点的更好的方式

class A 
{ 
// body 
}; 

class B : public A 
{ 
// body 
}; 

class C : public A 
{ 
// body 
}; 

class D : public A 
{ 
// body 
}; 

我想创建一个工厂功能,可以让我创建特定类型(BCD)的对象,并为返回一个指向它A类:

typedef std::shared_ptr<A> a_ptr; 

a_ptr createObject(int type) 
{ 
    switch(type) 
    { 
    case 0: 
     return a_ptr(new B()); 
    break; 
    case 1: 
     return a_ptr(new C()); 
    break; 
    case 2: 
     return a_ptr(new D()); 
    break; 
    } 
} 

然后,如果我有例如B类型的指针,我想将工厂创建的对象指定给B。对我而言,唯一合理的解决方案是:

std::shared_ptr<B> b = std::shared_ptr<B>(dynamic_cast<B*>(createObject(0))); 

但它看起来很丑。有没有更好的解决方案?或者,也许我应该尝试用我的函数创建对象的不同方式?

+2

如果您基于运行时值创建对象(这里是'int type'),那么就没有可能返回值被“正确”键入(如果'createObject'是一个模板,这将是可能的,但然后你只能够静态创建),所以需要强制转换。你可以设计*隐藏它的方式,但恕我直言,这不是一个好主意。演员应该是突出的。 – Jon 2013-03-07 13:14:50

+1

C++是静态类型的。也就是说,你必须在编译时知道每个表达式的类型。 (在你的情况下,应该是'A'类型。) – 2013-03-07 13:15:59

+2

请注意,'shared_ptr's有自己的[cast methods](http://en.cppreference.com/w/cpp/memory/shared_ptr/pointer_cast)。 – 2013-03-07 13:18:04

回答

5

如果要执行运行时垂头丧气的一个shared_ptr的,而使用std::dynamic_pointer_cast<>

std::shared_ptr<B> b = std::dynamic_pointer_cast<B>(createObject(0)); 

如果该对象被创建的类型是在运行时决定的,而你是一个尝试以检查返回的对象是否具有类型B,那么我看不到比动态向下转换更好的替代方法。

在另一方面,如果你知道 100%的把握尖锐的物体的类型为B,那么你可以使用std::static_pointer_cast<>

std::shared_ptr<B> b = std::static_pointer_cast<B>(createObject(0)); 

在您100%的把握知道这一刻,但是,我不明白为什么这样的指令不应该成为:

std::shared_ptr<B> b = std::make_shared<B>(); 
+1

另外,我认为重要的是要注意,在大多数情况下,动态投射的需要是代码异味。你有你的共同基础类,所以你可以避免投射。虚函数应该让你得到每个类的不同行为。如果你需要转换来访问派生类中的某些东西,那么你的调用代码将是一个很大的if-else或switch case,这表明你的类可能不应该从一个公共基础派生出来。 – 2013-03-07 13:30:10

1

对于少数“类型”你的createObject看起来不错。如果有很多“类型”,它只会变得很难看。然后,您可以通过为相应类的工厂函数创建表格映射类型来获得更好的效果。例如:

std::map<int, std::function <a_ptr()> > dispatcherTable = 
{ 
    {0, createB }, 
    {1, createC }, 
    {2, createD } 
}; 

然后,你可以用你的“类型”的一个索引表:

new_a = dispatcherTable[a](); 

那些“createB”,“createC”等可能的静态成员的工厂类或B,C等类的静态成员。你想要的任何方式。

+0

这可行,但开关柜更具可读性。我认为这不是OP询问的问题。 – 2013-03-07 13:25:37

相关问题