假设我有一个类似
的接口类class car {
public:
virtual void move(double x, double y) = 0;
// etc etc
};
和许多派生类如
class model8556 : virtual public car {
private:
void move(double x, double y) {
// ...
}
// etc etc
};
我通过
选择模型car* myCar;
switch (foo) {
case 1: myCar = new model3434(); break;
case 2: myCar = new model8295(); break;
// etc
}
是否有一种隐藏切换代码的好方法,可能会将其移至car
类本身?我可以在car
周围包装另一个类(?)(或者只是将开关代码移动到一个全局函数?),但我想知道是否有更优雅的东西。
感谢任何帮助。
答案 0 :(得分:3)
将开关代码提取到单独的函数当然是值得的,因为您希望避免在代码周围复制它。
您可以将它放在类的静态函数中。有些人会把它放在Car
本身,但我不推荐它,因为它将Car
耦合到派生类,你必须小心循环依赖。有些人会将它作为自己类的静态函数。这有时被描述为Simple Factory。
但是在C ++中,将它放在非成员函数中并没有错:
#include <memory>
class Car {
public:
virtual ~Car() {}
virtual void move(double x, double y) = 0;
};
class Model3434 : public Car {
public:
void move(double, double) override { }
};
class Model8295 : public Car {
public:
void move(double, double) override { }
};
std::unique_ptr<Car> createCar(int foo) {
switch (foo) {
case 1: return std::make_unique<Model3434>();
case 2: return std::make_unique<Model8295>();
default: return nullptr;
}
}
int main() {
auto car1 = createCar(1);
auto car2 = createCar(2);
}
我使用unique_ptr
而不是原始指针,因为我认为拥有指针是一种很好的做法,但它应该大致相当。
最好将枚举传递给工厂函数而不是整数。
也许值得在名称空间中使用工厂函数,最好在与Car
相同的名称空间中,以避免污染全局名称空间。
答案 1 :(得分:1)
在您的情况下,将创建逻辑隐藏在静态方法中就足够了。
static car* CreateInstance(int id)
{
case(id)
// etc etc
}
如果您感兴趣,那么您尝试获取的模式称为Factory Pattern,并且在创建逻辑变得更加复杂时非常有用。
答案 2 :(得分:1)
在c ++中有一种工厂模式可以促进这种事情。
以下是伪代码: -
class CarFactory
{
public:
static Car* createNewCar(std::string cartype )
{
if ( cartype == bmw )
return new BMW();
if ( cartypr == GALLARDO )
return new GALLARDO ();
}
};
在调用例程时,您可以执行
BMW* bmw = CarFactory::createNewCar( bmw );
它与你的if / else块基本相同,唯一的是它将对象创建在一个地方进行本地化,以避免维护问题。
答案 3 :(得分:1)
我会警惕将工厂放在car
界面内。您需要在制作新车型时随时更改此信息。
如果您将定义保持在行外,则在cpp文件中并将其放在静态类中,因为其他答案表明这将起作用。但是,如果你这样做,汽车在其子类型上具有依赖性,尽管是间接的。将创建功能保持为自由功能意味着您可以添加没有此缺陷的类型。
您可以使用汽车所在的命名空间,而不是将其放在全局命名空间中。
更一般地说,就界面而言 - 如果它是汽车和汽车制造工厂,那么car
的唯一责任是什么?这对我来说这个功能应该在其他地方。
答案 4 :(得分:0)
这看起来像你想要factory pattern并提供create()
(或其所谓的)模型类型(可能是枚举?)。
// .hpp
class factory
{
public:
static car* create(int model);
}
// .cpp
car* create(int model)
{
switch(model)
{
// decide which car to make
}
}
注意:代码甚至没有经过轻微测试,所以如果它不能正常工作我会道歉。