覆盖私有函数

时间:2018-02-13 19:21:01

标签: c++ c++11 inheritance

我正在研究一个类(称为类D),它派生自一个类(称为类B),并将由另一个类继承(称为类E)。我希望E类的实例能够访问其父级的所有公共函数,但我特别希望防止类E覆盖父类中的任何虚函数。

我认为通过覆盖D类私有部分中的函数,它会阻止派生类重写,但看起来并非如此。这将编译并运行E类中的函数:

var options = {
    stack: false,
    editable: true,
    zoomable : false,
    start: new Date(2018,1,13,12,0,0),
    end: new Date(2018,1,14),
};

var groups = new vis.DataSet([
    {id: 1, content: 'Bar'},
    {id: 2, content: 'Foo'}
]);

var id = 0;

var items = new vis.DataSet([
    {id: id++, content: '', className:'bg-danger', editable: { updateTime: false, updateGroup: true, remove: false }, start: '2018-02-13T18:00:00', end: '2018-02-13T20:00:00', group: 1},
    {id: id++, content: 'Nathan', className:'bg-success', editable: { updateTime: true, updateGroup: true, remove: false }, start: '2018-02-13T20:00:00', end: '2018-02-14T08:00:00', group: 1},
    {id: id++, content: 'Charles', className:'bg-success', editable: { updateTime: false, updateGroup: true, remove: false }, start: '2018-02-13T18:00:00', end: '2018-02-13T20:00:00', group: 2},
    {id: id++, content: 'Flavie, Vincent', className:'bg-warning', editable: { updateTime: true, updateGroup: true, remove: false }, start: '2018-02-13T20:00:00', end: '2018-02-14T08:00:00', group: 2},
]);

var container = document.getElementById('visualization');
var timeline = new vis.Timeline(container, items, groups, options);

因此有两个问题: 为什么我可以覆盖祖父母中虚拟但在父母中不是虚拟的函数? 为什么我可以覆盖祖父母中受保护但在父母中隐私的功能?

我在g ++和clang中尝试了它并且编译时没有错误或警告(-Wall -Wextra -Wpedantic)

1 个答案:

答案 0 :(得分:7)

  

为什么我可以覆盖祖父母中虚拟但在父母中不是虚拟的函数?

没有这样的事情。一旦函数被声明为虚拟,它就会在所有派生类中隐式虚拟。只有这样才能接近" unvirtualize"成员函数是声明它final。这将使得无法进一步覆盖它,但是当通过祖先引用/指针调用时,它仍然会受到动态调度的影响。但是,通过声明为final的孩子或其死者的任何访问都可以静态解决。

  

为什么我可以覆盖祖父母中受保护但在父母中隐私的功能?

访问说明符不会影响名称的可见性。它们仅影响可以使用该名称的位置。定义相同的函数将覆盖父实现,并由动态调度调用。同样,因为这不属于"访问"这个名字。

如果父母在父母中是私人的,那么孩子不能参考父母的实施(Parent::foo),并且外部代码也不能使用该界面。它确保仅以受控方式调用该功能。非常适用于测试前后条件。