【问题标题】:virtual methods inheritance class虚方法继承类
【发布时间】:2014-01-17 11:39:44
【问题描述】:

我有:

class A
{
   virtual void get();
}

class B: public A
{
   void get();
}

class C: public B
{
   void get();
}

int main()
{
   B     *i;

   i = new C();
   i.get();
   return (0);
}

如果 A::get() 是虚拟的:

i.get() 调用 C::get()

如果 A::get() 不是虚拟的:

i.get() 调用 B::get()

我的问题是:

为什么我不需要在 B::get() 上加上 virtual 来使用 C::get() 和 B.get()?

【问题讨论】:

  • 那不是真正的代码。 virtual get();
  • 应该是 virtual int get() 之类的东西。

标签: c++ inheritance virtual


【解决方案1】:

从基类覆盖虚方法的方法也将是隐式虚的 - 这适用于整个 ihneritance 链。

struct A {
    virtual int f(int);
};

struct B : A {
    int f(int); // overrides A::f, implicitly virtual
    void g(float);
};

struct C : B {
    int f(int); // overrides B::f, implicitly virtual
    int f(char);  // doesn't override anything, not virtual
    void g(float); // doesn't override and isn't virtual,
                   // because B::g is not virtual either.
                   // It hides B::g instead.
};

【讨论】:

  • 正确的做法应该是在B和C中显式地放入virtual呢?
  • @nsvir - 将它们标记为虚拟也是一个好习惯。 C++11 也有 override 关键字 (en.cppreference.com/w/cpp/language/override),如果您的编译器支持,这是标记方法的更好方法。
【解决方案2】:

成员函数 在基类中声明为 virtual 时,所有子类也将是 virtual。您可以在子类中省略 virtual 关键字这一事实并不意味着它不是虚拟的。

您对您提出的代码的假设如下:

int main()
{
   B* i;
   i = new C();
   i.get();
   return (0);
}

被上面的代码won't even compile 误导了(即使您在每个类声明/定义的末尾添加了分号)。

当您处理指针并且想要调用成员函数时,您可以取消引用指针并使用. 运算符:

(*ptr).function();

或使用-> 运算符:

ptr->function();

您的代码两者都没有。但假设您的实际意思是:

int main()
{
   B* i = new C();
   i->get();
}

你的假设是正确的:

  • 如果A::get是虚拟的,在i->get中,C::get会被调用
  • 否则将调用B::get

为什么我不需要在 B::get() 上加上 virtual 来使用 C::get()B.get()

你没有。 void get() 成员函数从基类一直到 C 类都是虚拟的。您不需要重复 virtual 关键字,但实际上我会推荐它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-09
    • 1970-01-01
    • 1970-01-01
    • 2011-03-03
    • 2016-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多