【发布时间】:2014-01-12 09:33:22
【问题描述】:
我有一个关于接口的问题,比如说:
class IAnimal
{ ...
Public:
virtual void makeSound() = 0;
};
class Cat : public IAnimal
{ ...
void makeSound() { std::cout << "purr" << std::endl; }
};
class Dog : public IAnimal
{ ...
void makeSound() { std::cout << "bark" << std::endl; }
};
class AnimalFactory
{
std::shared_ptr<IAnimal> createAnimal(animalType type)
{
std::shared_ptr<IAnimal> animal;
switch(type)
{ case animal_type::cat: animal = std::shared_ptr<Cat>(); break;
case animal_type::dog: animal = std::shared_ptr<Dog>(); break;
… }
return animal;
}
};
class App
{ ...
std::shared_ptr<IAnimal> _animal;
AnimalFactory::animal_type type;
void haveCat()
{ ...
type = AnimalFactory::animal_type::cat;
_animal = AnimalFactory.createAnimal(type);
_animal->makeSound();
...
}
};
现在,我需要这只猫来抓老鼠 无效的catchMouse() { std::cout
void haveCat()
{ ...
type = AnimalFactory::animal_type::cat;
_animal = AnimalFactory.createAnimal(type);
_animal->makeSound();
// catchMouse();
...
}
有几种可能的解决方案,但都不是很好。
- 在 IAnimal 中添加一个方法,然后在使用 AnimalFactory 创建猫之后,我可以从 IAnimal 调用 catchMouse() 方法。 但是 catchMouse 并不适用于所有动物,狗不要 catchMouse。向 IAnimal 中添加方法会污染界面,闻代码。
-
在 Cat 中添加一个公共方法 catchMouse(),并在 haveCat() 方法中将 _animal 强制转换为 Cat。
{ _cat = std::dynamic_pointer_cast<Cat>(AnimalFactory.createAnimal(type)); _cat->makeSound(); _cat->catchMouse(); }但是有一个动态演员表,不好,对吧?
让Cat实现IAnimal接口,还有一个关于Mouse的接口,但是AnimalFactory只返回std::shared_ptr, 而且我们不能在 IAnimal 中调用 catchMouse。
我在这里的意思是,一个子类中有一个公共方法,而另一个子类没有,如果我们使用工厂,如何设计它。 请不要回复,让狗抓兔子,然后在IAnimal中添加catch()方法,这样,猫抓老鼠,狗抓兔子。
这个问题有什么好的解决方案?谢谢。
【问题讨论】:
-
为什么要这么具体?
find_food、collect_food、consume_food之类的就足够了。 -
makeSound看起来应该是一个虚函数。 -
你已经用#2 回答了你自己的问题。当你需要一只猫时,你必须施放它。
-
这听起来像是在滥用
shared_ptr。 -
如果您要根据类型进行显式分支,不妨扔掉所有面向对象的废话,并像真正的男人在编写真正的程序时那样说
switch (animal->type) { case CAT: ...。跨度>
标签: c++ inheritance interface subclass factory