10

自从我学习了 C++ 以来,我一直想阻止隐藏基类非虚拟函数,但我不确定这是否合乎道德,但 C++ 11 的特性给了我一个想法。假设我有以下内容:

基地.h....

#ifndef baseexample_h
#define baseexample_h

#include <iostream>

class Base{
    public:  
    void foo() {
        std::cout << "Base.foo()\n" << std::endl;
    }
};

class Derived: public Base{ 
    public:
    void foo(){
        std::cout << "Derived.foo()\n" << std::endl;
    }   
};

#endif

和 main.cpp...

#include "bases.h"
#include <iostream>

int main()
{

    Base base;
    Derived derived; 

    base.foo();
    derived.foo();

    std::cin.get();

    return 0;
};

输出当然是

Base.foo()

Derived.foo()

因为派生的 foo() 函数隐藏了基本的 foo 函数。我想防止可能的隐藏,所以我的想法是将头文件基本定义更改为:

//.....
class Base{
    public:  
    virtual void foo() final {
        std::cout << "Base.foo()\n" << std::endl;
    }
};

class Derived: public Base{ 
    public:
    void foo(){ //compile error
        std::cout << "Derived.foo()\n" << std::endl;
    }   
};
//......

这似乎通过编译器错误来强制执行我想要的,防止覆盖和/或隐藏在 c++ 中,但我的问题是,这是一个好习惯,因为 foo() 从来都不是一个虚函数?由于我有点滥用virtual 关键字,这有什么缺点吗?谢谢。

4

1 回答 1

5

我会说,是的,这是不好的做法。您在不需要时引入了多态性,只是为了防止名称隐藏。

但是隐藏名字有什么不好呢?显然,无论出于何种原因,设计都Derived希望将函数隐藏foo在其基类中;这就是它所做的——也许它自己调用Base::foo然后执行一些在Derived.

试图颠覆已经够糟糕的了;尝试通过选择您不想要的语言功能来做到这一点甚至更糟。

如果您确实需要调用基本函数,请使用derived.Base::foo(),但请注意,您实际上破坏了 class 的 API Derived,您应该按照文档说明使用它。

于 2013-07-14T17:38:59.627 回答