C ++从已实现的虚拟类中调用非虚方法

时间:2013-03-19 14:32:03

标签: c++ methods interface virtual

我有一个也有普通方法的界面,我怎么称它呢?

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没有这种方法,我知道当然, 但哪种方式最好称之为

3 个答案:

答案 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
}

如您所见,如果您的设计很好,问题就会消失。