我正在研究一个类(称为类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)
答案 0 :(得分:7)
为什么我可以覆盖祖父母中虚拟但在父母中不是虚拟的函数?
没有这样的事情。一旦函数被声明为虚拟,它就会在所有派生类中隐式虚拟。只有这样才能接近" unvirtualize"成员函数是声明它final
。这将使得无法进一步覆盖它,但是当通过祖先引用/指针调用时,它仍然会受到动态调度的影响。但是,通过声明为final
的孩子或其死者的任何访问都可以静态解决。
为什么我可以覆盖祖父母中受保护但在父母中隐私的功能?
访问说明符不会影响名称的可见性。它们仅影响可以使用该名称的位置。定义相同的函数将覆盖父实现,并由动态调度调用。同样,因为这不属于"访问"这个名字。
如果父母在父母中是私人的,那么孩子不能参考父母的实施(Parent::foo
),并且外部代码也不能使用该界面。它确保仅以受控方式调用该功能。非常适用于测试前后条件。