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

Car*_*arl 1 c++ inheritance virtual-functions

基类专门声明该方法是非虚拟的.它适用于Visual Studio 2008,2010和2012以及ideone使用的任何编译器(gcc 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;
}
Run Code Online (Sandbox Code Playgroud)

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

#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;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:

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

And*_*owl 6

1.这合法吗?

是的.

2.它为什么有效?

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

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

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

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"!    
Run Code Online (Sandbox Code Playgroud)