【问题标题】:C++ Calling a non-virtual method from an implemented virtual classC++ 从已实现的虚拟类调用非虚拟方法
【发布时间】:2013-03-08 07:02:28
【问题描述】:

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

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

【问题讨论】:

    标签: c++ methods interface virtual


    【解决方案1】:

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

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

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

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

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

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

    【讨论】:

    • 真的谢谢,不知道,我会用 Cow* c = new Cow();确实!
    【解决方案2】:

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

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

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

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

    【讨论】:

      【解决方案3】:

      为了更好地解释我自己,我将使用真实姓名代替占位符:

      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
      }
      

      好吧,这当然是一个错误:你到底为什么要创建一个通用的Animalmoo?所以问题不在于如何在任何Animal 上调用moo;只是碰巧这个调用没有意义,编译器帮助我们注意到。

      现在,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
      }
      

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

      【讨论】:

      • 嗯,确实,您使用真实姓名而不是占位符的方式确实更清晰!会这样做 :) 但是谢谢,现在确实有了答案,应该只做一头牛 *c = 新牛!
      猜你喜欢
      • 1970-01-01
      • 2015-06-13
      • 2013-05-01
      • 2020-07-02
      • 1970-01-01
      • 2020-10-21
      • 1970-01-01
      • 2015-09-09
      • 1970-01-01
      相关资源
      最近更新 更多