C++:在基类中不是虚拟方法时,在派生类中声明虚拟方法是否合法?

标签 c++ inheritance virtual-functions

基类专门声明该方法是非虚拟的。 它适用于 Visual Studio 2008、2010 和 2012 以及 whatever compiler ideone uses (海合会 4.7+?)。

#include <iostream>

class sayhi
{
public:
    void hi(){std::cout<<"hello"<<std::endl;}
};

class greet: public sayhi
{
public:
    virtual void hi(){std::cout<<"hello world"<<std::endl;}
};


int main()
{
    greet noob;
    noob.hi(); //Prints hello world
    return 0;
}

这也有效 - 该方法在基类中是私有(private)的和非虚拟的:

#include <iostream>

class sayhi
{
private:
    void hi(){std::cout<<"hello"<<std::endl;}
};

class greet: public sayhi
{
public:
    virtual void hi(){std::cout<<"hello world"<<std::endl;}
};


int main()
{
    greet noob;
    noob.hi(); //Prints hello world
    return 0;
}

我的问题是:

  1. 这合法吗?
  2. 为什么有效?

最佳答案

1 . Is it legal?

2 . Why does it work?

没有什么能阻止您在派生类中声明与基类的成员函数同名的成员函数。您在派生类中的函数将简单地隐藏基类的函数。顺便说一句,如果派生类中的函数恰好是 virtual,则子类可以覆盖它:

class howdy : public greet
{
public:
    // Overrides greet::hi()
    virtual void hi() { std::cout << "howdy world" << std::endl; }
};

但是,这不会以任何方式影响 sayhi::hi():特别是,派生类中仅存在一个 virtual 函数隐藏它不让它 虚拟。因此,当通过指针或对 basesayhi 实例的引用调用函数时,您不能期望虚拟分派(dispatch)起作用:

sayhi noob;
noob.hi(); // Will NOT print "hello world"!

greet gentleman;
sayhi* p = &gentleman;
p->hi(); // Will NOT print "hello world"!

howdy neighbor;
p = &neighbor; 
p->hi(); // Will NOT print "howdy"!

greet* pG = &neighbor;
pG->hi(); // WILL print "howdy"!    

关于C++:在基类中不是虚拟方法时,在派生类中声明虚拟方法是否合法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15101601/

相关文章:

c++ - 为什么交换多维数组不是noexcept?

c# - 如何使用 C++ 静态库编译 C# 应用程序?

c# - Singleton 应该是可继承的还是不可继承的?

c++ - 虚拟表中的索引是如何在 C++ 中决定的?

C++ - Va_List(可变数字参数)未正确转换

scala - 从具有参数化类型参数的另一个方法调用具有参数化类型参数的方法时,保留特定结果类型参数

CSS ID 变体

c++ - 强制覆盖父类的所有虚函数,从子类

c++ - 继承,覆盖和虚函数,以避免重复代码

c++ - 为 C++ 打包/解包函数