我有一个也有普通方法的界面,我怎么称它呢?
class Animal{
virtual void virtualFunction()=0;
}
class Cow : Animal{
virtual void virtualFunction(){}
void nonVirtualFunction(){}
}
class main{
Animal *a = new Cow();
a->virtualFunction();
}
^:这可行,但是当我这样做...
a->nonVirtualFunction();
它说类 Animal没有这种方法,我知道当然, 但哪种方式最好称之为?
答案 0 :(得分:3)
如果您打算调用Cow
成员的函数,请不要将其存储在多态Animal
指针中:
Cow* c = new Cow();
c->nonVirtualFunction();
如果您要以Cow
特定的方式使用Animal*
,则Cow
中存储dynamic_cast
是没有意义的。
你可以使用Animal* a = new Cow();
if (Cow* c = dynamic_cast<Cow*>(a)) {
c->nonVirtualFunction();
}
在运行时检查对象的动态类型:
{{1}}
然而,这通常是设计糟糕的表现。
答案 1 :(得分:1)
您需要使用Cow指针来调用nonVirtualFunction。 Animal指针是指向具有Animal接口的Cow的SUBSET的指针。
调用nonVirtualFunction的唯一方法是获取Cow指针。
Cow *c = dynamic_cast<Cow*>(a);
会给你这样一个指针,假设一个确实指向一个牛。
答案 2 :(得分:1)
为了更好地解释自己,我将使用方法的实名而不是占位符:
class Animal{
virtual void move()=0;
}
class Cow : Animal{
virtual void move(){}
void moo(){}
}
int main () {
Animal *a = new Cow();
a->move();
a->moo(); // ERROR
}
嗯,当然这是一个错误:为什么你想要制作通用Animal
moo
?所以问题不在于如何在任何moo
上调用Animal
;只是这个调用没有意义,编译器帮助我们注意到。
现在,Animal
可能有一个非虚方法,可以在任何动物上调用,无需在子类上重写它,例如:
class Animal{
// Everything else, plus:
std::string Name() {return name;}
private:
std::string name;
}
int main () {
Animal *a = new Cow();
a->move();
std::string animalName = a->Name(); // OK
}
如您所见,如果您的设计很好,问题就会消失。