为了账号安全,请及时绑定邮箱和手机立即绑定

关于c++的一个有趣现象,具体看下面详细情况?

关于c++的一个有趣现象,具体看下面详细情况?

C++
BIG阳 2021-05-04 11:11:23
c++有趣现象:private的成员函数可以在类的外部调用?#include <iostream.h>class base;base * pbase;class base{public:base(){pbase=this;}virtual void fn(){cout<<"base"<<endl;}};class derived:public base{private:<br/> void fn()<br/> {cout<<"derived"<<endl;}};void main(){derived aa;pbase->fn();}以上程序在VC和VC7中输出结果为 derived, 哈,居然private的成员函数可以在类的外部调用.//我的问题是,难道这是真的吗?private的成员函数可以在类的外部调用.?//还是这个private关键字不应该使用?
查看完整描述

2 回答

?
慕容3067478

TA贡献1773条经验 获得超3个赞

它并不是C++的缺陷或是被设计者所忽视的问题。

当我们使用虚函数的时候,它的访问规则是在声明的时候被确定的,而不是在被“子类重写”(overridden)的时候,虚函数的访问规则不会受到来自被重写的子类函数的影响,更进一步说,当某个对象A的引用B(特指间接访问)用来调用该对象的虚函数时,对于该对象A的一切声明信息,都取决于该对象的引用B,而不是这个引用所引用的对象A。

C++标准里有对该问题的具体说明:当一个子类函数通过基类的指针调用时,访问权限取决于基类对该函数的声明。

参考C++ Standard ISO/IEC 14882:2003(E) 第11.6节:

11.6 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:
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]

Access is checked at the call point using the type of the expression used to denote the object for which the member function is called (B* in the example above). The access of the member function in the class in which it was defined (D in the example above) is in general not known.

至少我们在程序编译时无法获知这个指针的值,它会指向何种位置。

经验:private仅仅是一个访问限定符,它只限定函数和数据不能被“直接”访问,而不担保这些函数和数据会被通过其他方法间接地访问到,在成员函数中返回一个类私有数据成员的引用也是这个道理。



查看完整回答
反对 回复 2021-05-09
?
泛舟湖上清波郎朗

TA贡献1818条经验 获得超3个赞

发现新大陆了呵呵,不错,但是,它并不是C++的缺陷或是被设计者所忽视的问题。

当我们使用虚函数的时候,它的访问规则是在声明的时候被确定的,而不是在被“子类重写”(overridden)的时候,虚函数的访问规则不会受到来自被重写的子类函数的影响,更进一步说,当某个对象A的引用B(特指间接访问)用来调用该对象的虚函数时,对于该对象A的一切声明信息,都取决于该对象的引用B,而不是这个引用所引用的对象A。

C++标准里有对该问题的具体说明:当一个子类函数通过基类的指针调用时,访问权限取决于基类对该函数的声明。

参考C++ Standard ISO/IEC 14882:2003(E) 第11.6节:

11.6 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:
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]

Access is checked at the call point using the type of the expression used to denote the object for which the member function is called (B* in the example above). The access of the member function in the class in which it was defined (D in the example above) is in general not known.

至少我们在程序编译时无法获知这个指针的值,它会指向何种位置。

经验:private仅仅是一个访问限定符,它只限定函数和数据不能被“直接”访问,而不担保这些函数和数据会被通过其他方法间接地访问到,在成员函数中返回一个类私有数据成员的引用也是这个道理。

另外,如果不是特殊的需要,一般来说,这并不是一个好的设计,有点自找麻烦的味道!



查看完整回答
反对 回复 2021-05-09
  • 2 回答
  • 0 关注
  • 229 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信