private成员函数竟然可以在类的外部调用

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

[html] view plain copy print?

  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 <iostream>

using namespace std;
class Base
{
public:
	virtual void Func()
	{
		cout<<"base"<<endl;
	}
};

class Derived : public Base
{
private:
	void Func()
	{
		cout<<"derived"<< endl;
	}
};

int main()
{
	Base *d = new Derived;
	d->Func( );
	delete d;

	return 0;
}

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

[cpp] view plain copy print?

  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 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.

*/

    我们知道C++多态的包括编译时多态和运行时多态,而通过基类的指针或者引用调用虚函数时,会发生动态的绑定,而编译器的处理是静态的,它只会在调用该成员函数的时候,在当前类的作用域中进行访问控制检查(Base类或者B类中f函数是public的,因此可以通过编译器的检查),而对C++运行过程中的动态绑定(由于使用了基类的指针调用虚函数,程序运行时动态执行了子类的函数f())是不为所知,也就出现了上面的那段代码,外部直接调用了Derived的私有函数成员,而编译器却不为所知。

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

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

时间: 2024-10-05 17:05:39

private成员函数竟然可以在类的外部调用的相关文章

link环境下如何调用成员函数,如果这个类是abstrac的呢?

问题描述 link环境下如何调用成员函数,如果这个类是abstrac的呢? link环境下如何调用成员函数,如果这个类是abstrac的呢? 解决方案 那必须先继承一个抽象类,把抽象函数都实现了,然后去实例化这个类才行

成员函数-c++中关于类中的函数一些疑问

问题描述 c++中关于类中的函数一些疑问 1.网上看见两种说法,一个是函数放在code area 另一个是instruction area 请问两者一样吗,还是有什么区别 2.创建的对象中是不是有一个指针指向放在那个area的函数,那么函数在那个区域又是怎么存放的呢 3.使用拷贝构造函数的时候,怎么把成员函数拷贝过去,构造函数也要拷贝过去吗 4.创建对象用的是构造函数,那么对象创建好了之后,对象所在的内存中还有构造函数吗(就是说对象还可以使用够早函数吗) 5.还有我想知道,类的域 就是四个点,在

类的成员函数指针的使用方法

函数指针主要的目的是实现与运用相互分离,类的成员函数封装在类里面,运行需要相应的对象来调用,所以在调用这个类的成员函数时候,需要类的函数地址和这个类的对象.     以下是实现的类:     class A    {    public:void DoSth(){printf("A-DoSth");}    };    以下是调用的类:     typedef void (A::*PFun)(void);//声明类的函数指针     class B    {    public:   

C++类的成员函数(在类外定义成员函数、inline成员函数)

类的成员函数(简称类函数)是函数的一种,它的用法和作用和前面介绍过的函数基本上是一样的,它也有返回值和函数类型,它与一般函数的区别只是:它是属于一个类的成员,出现在类体中.它可以被指定为private(私有的).public (公用的)或protected(受保护的). 在使用类函数时,要注意调用它的权限(它能否被调用)以及它的作用域(函数能使用什么范围中的数据和函数).例如私有的成员函数只能被本类中的其它成员函数所调用,而不能被类外调用.成员函数可以访问本类中任何成员(包括私有的和公用的),可

怎么实现类的成员函数作为回调函数_C 语言

如果试图直接使用C++的成员函数作为回调函数将发生错误,甚至编译就不能通过.其错误是普通的C++成员函数都隐含了一个传递函数作为参数,亦即"this"指针,C++通过传递this指针给其成员函数从而实现程序函数可以访问C++的数据成员.这也可以理解为什么C++类的多个实例可以共享成员函数却-有不同的数据成员.由于this指针的作用,使得将一个CALL-BACK型的成员函数作为回调函数安装时就会因为隐含的this指针使得函数参数个数不匹配,从而导致回调函数安装失败.要解决这一问题的关键就

实例解析C++中类的成员函数指针_C 语言

C语言的指针相当的灵活方便,但也相当容易出错.许多C语言初学者,甚至C语言老鸟都很容易栽倒在C语言的指针下.但不可否认的是,指针在C语言中的位置极其重要,也许可以偏激一点的来说:没有指针的C程序不是真正的C程序. 然而C++的指针却常常给我一种束手束脚的感觉.C++比C语言有更严格的静态类型,更加强调类型安全,强调编译时检查.因此,对于C语言中最容易错用的指针,更是不能放过:C++的指针被分成数据指针,数据成员指针,函数指针,成员函数指针,而且不能随便相互转换.而且这些指针的声明格式都不一样:

C++中Operator类型强制转换成员函数解析_C 语言

类型转换操作符(type conversion operator)是一种特殊的类成员函数,它定义将类类型值转变为其他类型值的转换.转换操作符在类定义体内声明,在保留字 operator 之后跟着转换的目标类型.转换函数又称类型强制转换成员函数,它是类中的一个非静态成员函数.它的定义格式如下: 复制代码 代码如下: class <类型说明符1> { public: operator <类型说明符2>(); - } 这个转换函数定义了由<类型说明符1>到<类型说明符2

成员函数指针与高性能的C++委托 (Member Function Pointers and the Fastest Possible C++ Delegates)

标准C++中没有真正的面向对象的函数指针.这一点对C++来说是不幸的,因为面向对象的指针(也叫做"闭包(closure)"或"委托(delegate)")在一些语言中已经证明了它宝贵的价值.在Delphi (Object Pascal)中,面向对象的函数指针是Borland可视化组建库(VCL,Visual Component Library)的基础.而在目前,C#使"委托"的概念日趋流行,这也正显示出C#这种语言的成功.在很多应用程序中,&qu

link中的函数不是相当于静态函数么?为什么还可以调用成员函数,之前问错了,谢谢

问题描述 link中的函数不是相当于静态函数么?为什么还可以调用成员函数,之前问错了,谢谢 link中的函数不是相当于静态函数么?为什么还可以调用成员函数,之前问错了,谢谢 解决方案 关键是哪个类的成员函数和哪个类的静态函数.不能调用成员函数是指别的类的,如果这个函数在自己类的成员函数中调用,就可以.