现实世界中,托关系的现象屡见不鲜。托个关系,就能比别人少奋斗好多年,这未免让许多无背景的屌丝码农扼腕长叹。但更令人绝望的是,C++ 里竟也有类似的情况。
话不多说,上例子:
cpp
#include <iostream> using namespace std; class B { public: virtual void f() { cout << "virtual function" << endl; } }; class D : public B { private: void f() { cout << "private function" << endl; } }; int main() { D d; B* pb = &d; pb->f(); }
输出:
private function
对于 D
类来说,f()
分明是一个 private
的成员。我们却用了一些小手段,绕开了权限,成功的调用了它。这是不是有违 OO 的设计原则呢?
定定神,细细看,发现这原来是被爹给坑了。父类 B
中竟然为 f()
这个虚方法开了 public
权限。以至于无耻之辈,贿赂儿子碰了灰,竟去找他爹托关系!愣是让丫得逞了。。。
好吧,扯淡到此结束。这个例子其实脱胎于 C++11 的标准(草稿N3690)。
11.5 Access to virtual functions [class.access.virt]
- The access rules (Clause 11) for a virtual function are determined by its declaration and are not affected by the rules for a function that later overrides it. [Example:
cpp
class B { public: virtual int f(); }; class D : public B { private: int f(); }; void f() { D d; B* pb = &d; D* pd = &d; pb->f(); // OK: B::f() is public, // D::f() is invoked pd->f(); // error: D::f() is private }
—end example]
注意加粗的地方。虚方法的权限只由其声明确定,并不受后续 override 函数权限的影响。
以此为戒。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。