【发布时间】:2018-07-24 06:08:32
【问题描述】:
我正在研究一个从类(称为 B 类)派生的类(称为 D 类),并将被另一个类(称为 E 类)继承。我希望 E 类的实例能够访问其父类的所有公共函数,但我特别想防止 E 类覆盖父类中的任何虚函数。
我认为通过覆盖 D 类的私有部分中的函数可以防止派生类被覆盖,但情况似乎并非如此。这将编译并运行 E 类中的函数:
#include <iostream>
//an abstract base class
class b
{
public:
virtual ~b() = default;
protected:
virtual void print() = 0;
virtual void print_two()
{
std::cout << "base class" << std::endl;
}
};
class d: public b
{
public:
virtual ~d() = default;
private:
void print() override // note this is not virtual -adding final here does the trick
{
std::cout << "class d" << std::endl;
}
using b::print_two; //this doesn't work either
};
class e : public d
{
public:
void print() override //why is this possible given the function it's overriding is private and non-virtual?
{
std::cout << "class e" << std::endl;
}
void print_two() override //why is this possible given the function it's overriding is private and non-virtual?
{
std::cout << "print two class e" << std::endl;
}
};
int main()
{
e foo;
foo.print();
foo.print_two();
}
所以有两个问题: 为什么我可以覆盖在祖父母中是虚拟但在父母中不是虚拟的函数? 为什么我可以覆盖在祖父母中受保护但在父母中为私有的函数?
我在 g++ 和 clang 中尝试过,它编译时没有错误或警告 (-Wall -Wextra -Wpedantic)
【问题讨论】:
-
在
d,试试这个:virtual void print() override final { ... } -
"注意这不是虚拟的" 它实际上是虚拟的,所以你的一个前提是错误的。 (如果它不是虚拟的,您将无法
override它。) -
一旦函数被标记为
virtual,它就是sticky。它与所有子类中的函数保持一致。无法取消虚拟化函数。 -
另外,virtual 与访问级别无关。覆盖私有的东西可能非常有用(请参阅模板方法模式。)
标签: c++ c++11 inheritance