0

我有一个接口,它也有一个普通的方法,那我怎么称呼它呢?

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类没有这个方法,我当然知道,但是什么方法最好调用那个方法

4

3 回答 3

3

如果您要调用的成员函数,首先Cow不要将其存储在多态Animal指针中:

Cow* c = new Cow();
c->nonVirtualFunction();

如果您要以特定方式使用a ,则将 a 存储Cow在中是没有意义的。Animal*Cow

可以使用dynamic_cast在运行时检查对象的动态类型:

Animal* a = new Cow();
if (Cow* c = dynamic_cast<Cow*>(a)) {
  c->nonVirtualFunction();
}

然而,这通常是糟糕设计的标志。

于 2013-03-19T14:35:03.270 回答
1

您需要使用 Cow 指针来调用 nonVirtualFunction。Animal 指针是指向具有 Animal 接口的 Cow 的 SUBSET 的指针。

调用 nonVirtualFunction 的唯一方法是获取 Cow 指针。

Cow *c = dynamic_cast<Cow*>(a); 

会给你这样一个指针,假设 a 确实指向一头牛。

于 2013-03-19T14:35:11.277 回答
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?所以问题不在于如何调用mooany Animal;碰巧这个调用没有意义,编译器帮助我们注意到。

现在,anAnimal可能有一个非虚拟方法,可以在任何动物上调用,而无需在子类上重写它,例如:

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
}

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

于 2013-03-19T14:44:32.053 回答