博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
private成员函数竟然可以在类的外部调用
阅读量:7048 次
发布时间:2019-06-28

本文共 2567 字,大约阅读时间需要 8 分钟。

今天写代码竟然发现,private成员函数竟然可以在类的外部调用,开始以为是C++设计的缺陷。但是逐步深入才知道C++多态的博大精深。

[html]
  1. #include <iostream>  
  2.   
  3. using namespace std;   
  4. class Base  
  5. {  
  6. public:  
  7.     virtual void Func()  
  8.     {  
  9.         cout<<"base"<<endl;  
  10.     }  
  11. };  
  12.   
  13. class Derived : public Base  
  14. {  
  15. private:  
  16.     void Func()   
  17.     {  
  18.         cout<<"derived"<< endl;  
  19.     }  
  20. };  
  21.   
  22.   
  23. int main()  
  24. {  
  25.     Base *d = new Derived;  
  26.     d->Func( );  
  27.     delete d;  
  28.       
  29.     return 0;  
  30. }  
#include 
using namespace std; class Base{public: virtual void Func() { cout<<"base"<
Func( ); delete d; return 0;}

查看了一下资料,发下了下面的内容,这下一下子就明了了。

[cpp]
  1. /*参考C++ Standard ISO/IEC 14882:2003(E) 第11.6节: 
  2.  
  3. 11.6 Access to virtual functions [class.access.virt] 
  4.  
  5. The access rules (clause 11) for a virtual function are determined by  
  6. its declaration and are not affected by the rules for a function that  
  7. later overrides it.  
  8. [Example: 
  9. */  
  10. class B {  
  11. public:  
  12. virtual int f();  
  13. };  
  14. class D : public B {  
  15. private:  
  16. int f();  
  17. };  
  18. void f()  
  19. {  
  20. D d;  
  21. B* pb = &d;  
  22. D* pd = &d;  
  23. pb->f(); //OK: B::f() is public,  
  24. // D::f() is invoked  
  25. pd->f(); //error: D::f() is private  
  26. }  
  27. /*—end example] 
  28.  
  29. Access is checked at the call point using the type of the  
  30. expression used to denote the object for which the member  
  31. function is called (B* in the example above).  
  32. The access of the member function in the class in which  
  33. it was defined (D in the example above) is in general not known. 
  34.  
  35. */  
/*参考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 invokedpd->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.*/
    我们知道
C++
多态的包括编译时多态和运行时多态,而通过基类的指针或者引用调用虚函数时,会发生动态的绑定,而编译器的处理是静态的,它只会在调用该成员函数的时候,在当前类的作用域中进行访问控制检查(
Base
类或者
B
类中
f
函数是
public
,
因此可以通过编译器的检查),而对
C++
运行过程中的动态绑定
(
由于使用了基类的指针调用虚函数,程序运行时动态执行了子类的函数
f())
是不为所知,也就出现了上面的那段代码,外部直接调用了
Derived
的私有函数成员,而编译器却不为所知。

    我们可以想像:当一个子类的虚成员函数通过基类的指针调用时,访问权限取决于基类对该函数的声明,而C++privateproected仅仅是一个访问限定符,它只限定函数和数据不能被“直接”访问,而不担保这些函数和数据会被通过其他方法间接地访问到,在成员函数中返回一个类私有数据成员的引用,在外部就可以对这个私有属性进行修改(这个请参照博主的,对这个现象有说明)也是这个道理。

转载:http://blog.csdn.net/gatieme/article/details/17589981

你可能感兴趣的文章
《爱玩电脑》网站开发计划 2.0
查看>>
KVM下的桥接网卡配置
查看>>
ubuntu 终端位置
查看>>
RAC clusterware环境检查与补丁安装日志
查看>>
等价的交换,才有了等价的友谊。
查看>>
编写获取真实IP的工具类
查看>>
Linux信号(signal) 机制分析
查看>>
cisco asa5505 transparent v8.4&v7.2
查看>>
NAT技术基础解析
查看>>
求完数
查看>>
快速高效地开发和调试基于gradle管理的web应用
查看>>
500 OOPS: vsftpd: refusing to run with writable root inside chroot()
查看>>
SolrCloud+tomcat7+zookeeper集群配置
查看>>
Dubbo之服务暴露
查看>>
一点感叹
查看>>
使用Feign实现Form表单提交
查看>>
linux 压缩及归档
查看>>
Linux下的DNS
查看>>
floor和ceil函数的返回自是double型的
查看>>
14.3继承
查看>>