从基类指针访问派生私有成员函数到派生对象
#include <iostream>
using namespace std;
class B {
public:
virtual void fn1(void) {cout << "class B : fn one \n"; }
virtual void fn2(void) {cout << "class B : fn two \n"; }
};
class D: public B {
void fn1(void) {cout << "class D : fn one \n"; }
private:
void fn2(void) {cout << "class D : fn two \n"; }
};
int main(void)
{
B *p = new D;
p->fn1();
p->fn2();
}
为什么即使fn2,
在 p->fn2()
也会调用派生类函数D
中是私有的?
Possible Duplicate:
Why can i access a derived private member function via a base class pointer to a derived object?
#include <iostream>
using namespace std;
class B {
public:
virtual void fn1(void) {cout << "class B : fn one \n"; }
virtual void fn2(void) {cout << "class B : fn two \n"; }
};
class D: public B {
void fn1(void) {cout << "class D : fn one \n"; }
private:
void fn2(void) {cout << "class D : fn two \n"; }
};
int main(void)
{
B *p = new D;
p->fn1();
p->fn2();
}
Why does p->fn2()
call the derived class function even though fn2
is private in D
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
访问修饰符,例如
public
、private
和protected
仅在编译期间强制执行。当您通过指向基类的指针调用该函数时,编译器不知道该指针指向派生类的实例。根据编译器可以从这个表达式推断出的规则,这个调用是有效的。降低派生类中成员的可见性通常是语义错误。现代编程语言(例如 Java 和 C#)拒绝编译此类代码,因为在基类中可见的成员始终可以通过基指针在派生类中访问。
Access modifiers, such as
public
,private
andprotected
are only enforced during compilation. When you call the function through a pointer to the base class, the compiler doesn't know that the pointer points to an instance of the derived class. According to the rules the compiler can infer from this expression, this call is valid.It is usually a semantic error to reduce the visibility of a member in a derived class. Modern programming languages such as Java and C# refuse to compile such code, because a member that is visible in the base class is always accessible in the derived class through a base pointer.
调用
p->fn2()
在运行时根据p
指向的对象类型进行评估。在编译时,编译器将p->fn2()
调用视为对B::fn2()
的调用,并且自B::fn2()< /code> 是公共的,编译器不仅仅报告错误。仅在运行时才会评估实际的函数调用
D::fn2()
。这并没有违反
封装
原则,这是 C++ 的一项功能,称为运行时多态性
或动态多态性
The call
p->fn2()
is evaluated at run time depending on the type of objected pointed byp
. At compile time the compile sees thep->fn2()
call as call toB::fn2()
and sinceB::fn2()
is public the compiler doesn't report only error. It is only at runtime that actual function callD::fn2()
is evaluated.This doesn't break the
Encapsulation
principle this is a feature of C++ calledRun-time Polymorphism
orDynamic Polymorphism
当您执行
p = new D
时,p->__vfptr
现在指向D
的虚拟函数表的开头。由于这种情况发生在运行时,因此访问说明符不会发挥作用。When you do
p = new D
,p->__vfptr
is now pointing to the start of the virtual function table ofD
. And since this happens at runtime, therefore, access specifiers don't come into play.来自维基百科:
HTH。
From wikipedia:
HTH.