【发布时间】:2017-06-29 21:37:05
【问题描述】:
我遇到的问题与此处提出的问题非常相似: Using derived methods that aren't in the base class
在那个问题中,IdeaHat 提供的最佳答案是使用 dynamic_cast,但他/她接着说,如果你不得不求助于它,那么你的设计就是糟糕的。我注意到其他问题的答案非常相似。
那么,在这种情况下,正确的设计是什么?
为了便于讨论,我们使用以下代码:
enum AnimalType {
dog = 0,
cat
}
Class Animal {
virtual AnimalType getType() = 0;
void eat() {
cout << "Ate some food!" << endl;
}
void sleep() {
cout << "Zzzz..." << endl;
}
};
Class Dog : public Animal {
AnimalType getType() {
return AnimalType::dog;
}
void fetch() {
cout << "Fetched the stick!" << endl;
}
};
Class Cat : public Animal {
AnimalType getType() {
return AnimalType::cat;
}
};
//A factory function
Animal* shelter(AnimalType type) {
if(type == AnimalType::dog) {
return new Dog;
}
else {
return new Cat;
}
int main() {
Animal* pet = shelter(AnimalType::dog);
pet->fetch();
}
基本上,我有一家工厂生产特定类的多个子类。一些子类包含父/其他子类中不存在的函数,这将阻止在没有解决方法的情况下使用多态性。
我将如何以一种可行的方式实现这一点,并且也被认为是“好的设计”?
【问题讨论】:
-
深入了解。问问自己,你做了什么让自己处于 A) 你有一个通用的
Animal和 B) 你需要向fetch提问。 A 或 B 都错了,你只能通过看你的整体设计来知道哪一个,而不是一堆随机的动物测试类。 -
您可以查看visitor Pattern,然后有一个访问者供您使用,除了会抓取的狗之外什么都不做。
-
@Jarod42,这看起来很有可能;我必须更仔细地调查。
-
@Nicol Bolas,我不确定为什么这些是互斥的。如果我理解你的意思,你是说如果我想让我的 Dog 获取(),我不应该从 Animal 继承?
-
@AndrewKline:“我不知道为什么它们是互斥的。”因为不是所有的
Animals 都可以fetch;这就是Animal没有fetch函数的意思。如果你向函数传递一个Animal对象,那么它应该只做所有Animal对象都可以做的事情。如果该函数需要生成它传递的fetch,那么它传递的不应该是Animal。所以这归结为你是如何让自己陷入如此矛盾的境地的问题。而你的例子并没有表明这一点;太人工了。
标签: c++ inheritance polymorphism