C++对于类访问权限public,protected,private的深刻理解

来源:互联网 发布:端口类型以太网 编辑:程序博客网 时间:2024/05/22 06:16

本帖转自网络,查找不到原作者,如有冒犯,深表歉意!

 1 #include <IOSTREAM> 2 using namespace std; 3  4 class A{ 5 public: 6     A(int i_,int j_) 7     { 8         i=i_; 9         j=j_;10     }11     void disp(A &a)12     {13         cout<<a.i<<endl<<a.j<<endl;14     }15 16 private:17     int i;18 protected:19     int j;20 };21 22 int main(int argc, char* argv[])23 {24     A a(123,456);25     A b(789,543);26     a.disp(b);27     b.disp(a);28 29     return 0;30 }

访问修饰符的作用是以类为单位还是以对象为单位?

    初看起来,倒是会产生疑问。为什么会这样,是否有bug?    仔细考究起来,我们其实可以这样看待类和对象:类是将数据成员和进行于其上的一系列操作(成员函数)封装在一起,注意:成员函数可以操作数据成员(可以称类中的数据成员为泛数据成员)!对象是类的实例化,怎样理解实例化?其实每一个实例对象都只是对其中的数据成员初始化,内存映像中每个对象仅仅保留属于自己的那份数据成员副本。而成员函数对于整个类而言却是共享的,即一个类只保留一份成员函数。那么每个对象怎样和这些可以认为是“分离”的成员函数发生联系,即成员函数如何操作对象的数据成员?记住this指针,无论对象通过(.)操作或者(->)操作调用成员函数,编译时刻,编译器都会将这种调用转换成我们常见的全局函数的形式,并且多出一个参数(一般这个参数放在第一个),然后将this指针传入这个参数。于是就完成了对象与成员函数的绑定(或联系).实例化后就得到同一个类的多个不同的对象,既然成员函数共享的,那么成员函数就可以操作对象的数据成员。    问题是现在有多个对象,成员函数需要知道操作的是哪个对象的数据成员?    比如有对象obj1和obj2,都属于A类,A类有public成员函数foo()。如果obj1调用该函数,编译时会给foo函数传入this指针,obj1,foo中操作obj1自身的成员就不用任何修饰,直接访问,因为其中的数据成员自动根据this指针找到。如果obj1调用该函数,同样可以访问同类的其他对象的数据成员!那么你需要做的是让foo函数知道是同类对象中哪个对象的数据成员,一个解决办法是传入同类其他对象的指针或引用,那么就可以操作同类其他对象的数据成员。    例如:foo(A &obj)这样定义,然后调用:obj1.foo(obj2)就可以在obj1访问obj2的数据成员,而无论这些数据成员是private还是protected。
总结:C++的访问修饰符的作用是以类为单位,而不是以对象为单位。通俗的讲,同类的对象间可以“互相访问”对方的数据成员,只不过访问途径不是直接访问。步骤是:通过一个对象调用其public成员函数,此成员函数可以访问到自己的或者同类其他对象的public/private/protected数据数据成员和成员函数(类的所有对象公用),而且还需要指明是哪个对象的数据成员(调用函数对象自己的成员不用指明因为有this指针;其他对象的数据成员可以通过引用或指针间接指明。)

谁要控制谁的访问权限?

    顾名思义,private/public/protected 分别表示 私有/公开/保护,它们是一组用于访问权限控制的关键字。那么首先,需要澄清的一个关键点是,是要控制谁访问谁的权限?这个访问的主语(施事)是谁?宾语(受事)是谁?    我们经常听到这样的说法:
  1. 一个类友元可以访问该类的任何成员(包括成员变量及成员方法,下同)。
  2. private成员只有该类自身可以访问,protected成员只有该类及其派生类可以访问,public成员所有的人都可以访问。
宾语(受事)是谁这一点很明确,是类的成员(包括成员变量及成员方法)。主语(施事)是谁?这是让大家发生混淆的关键点。也是这个说法中含糊不清的地方。想清楚一点,其实主语(施事)指的是一个函数,而不是(当然更不是变量)。private/public/protected要控制的是一个函数(施事)对一个类的成员(包括成员变量及成员方法)的访问权限。因此比较完整的说法是:1)一个类友元(包含友元函数或者友元类的所有成员函数)可以访问该类的任何成员(包括成员变量及成员方法)。2)除去友元外,private成员只有该类自身的成员函数可以访问,protected成员只有该类的成员函数及其派生类的成员函数可以访问,public成员则所有的函数都可以访问。也就是说,当我们说一个类可以访问XXX,其实暗指这个类的成员函数可以访问XXX。了解了这一点,外加一条显而易见的规则,上面的问题就不难回答了。这条规则是:3)派生类在继承时可削弱成员的访问权限(通过protected/private修饰)。例如上面的例子class P : protected O {…}; 那么某个函数通过类P访问O中成员时,该函数对类O中的public成员只有protected权限。

0 0