我对Interface有疑问,让我们说:
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();
...
}
};
现在,我需要这只猫抓老鼠 void catchMouse() {std :: cout&lt;&lt; “抓老鼠”; }
void haveCat()
{ ...
type = AnimalFactory::animal_type::cat;
_animal = AnimalFactory.createAnimal(type);
_animal->makeSound();
// catchMouse();
...
}
有几种可能的解决方案,但看起来都不好。
在Cat中添加一个公共方法catchMouse(),并在hasCat()方法中将_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()方法,这样,猫可以抓老鼠,狗可以抓兔子。
这个问题的好方法是什么?感谢。
答案 0 :(得分:0)
我不认为你实际上可以从shared_ptr转换为Cat,是吗?因此,在不了解您的代码库的情况下,我编写了一个小型测试程序,
#include <memory>
#include <string>
#include <iostream>
class IAnimal
{
public:
virtual void makeSound(){}
};
class Cat : public IAnimal
{
public:
virtual void makeSound() { std::cout << "purr" << std::endl; }
void catchMice(void){
std::cout<<"mouse catched\n";
}
};
class Dog : public IAnimal
{
virtual void makeSound() { std::cout << "bark" << std::endl; }
};
int main(int argc,char** argv){
Cat* c = new Cat;
std::shared_ptr<IAnimal> s(c);
//you've basically got something of this sort don't you?
s->makeSound();
(static_cast<Cat*>(s.get()))->catchMice();
return 0;
}
应该做你想做的事。我想你可能想把makeSound(void)作为一个虚函数。
答案 1 :(得分:0)
我想,处理问题的方法是解决方案的变化2:使用特殊方法catch创建特定的接口ICatcher并执行以下操作:
AnimalFactory::animal_type type = AnimalFactory::animal_type::cat;
std::shared_ptr<IAnimal> animal = myAnimalFactory.createAnimal(type);
(dynamic_cast<ICatcher*>(animal.get()))->catch();
但在这里你应该确保dynamic_cast会成功或者提供额外的检查。
也许,您也会对超级接口COM及其QueryInterface方法在IUnknown中如何解决此问题感兴趣。可以为该架构实现本地版本。