(笔记):组合and继承之访问限制(一)

  下面在介绍组合与继承之前,先介绍一下访问限制,访问限制:public、protected、private三者是按照授权的大小排序的。这里有个博客,对这三者有了经典的诠释。
http://blog.csdn.net/artechtor/article/details/2295739
下面先介绍public and private,而protected在继承那里在说。
public: 是指类的内部东西都是公有的,它的访问域在任何地方都可以,比如Class A,A a ; 此时可以用a.的方式使用类中的任意public变量和函数。这个比较简单就不举例子了。
private: (使用与成员变量和成员函数)仅仅属于同一类本身可以访问。
这句话就是说,仅仅可以通过类的成员函数可以访问(作用域仅仅在类的声明那段里)。所以即使在其他函数中用Class A定义一个对象,然后用A.ii 也是不能访问私有成员变量,也就是说private 的变量只能通过成员函数来访问(直接或者间接的使用成员函数的方式)。
第一种:对象直接调用 public成员函数的方式(这个成员函数内部访问了private的成员),来访问private属性的成员函数函数或者成员变量。
第二种:一个同类对象可调用类的public成员函数(形式参数为指向该类的指针或者引用,或者对象本身)来访问同一个类的另一个对象的私有成员变量,进而来访问这个类的private成员变量
下面分别举例说明两种情况。
第一种:
代码和结果如下:

 1 #include<iostream>
 2 using namespace std;
 3 
 4 class A{
 5     private:
 6         int i;
 7     public:
 8         A():i(10){}
 9         void print(){
10             cout<<"A.i = "<<i<<endl;
11         }
12 };
13 
14 int main()
15 {
16     A a;
17 //    a.i;         //这里取消注释的话就会编译错误 提示 i 是private变量 
18     a.print();    
19     
20     return 0;
21 }
View Code

结果:

第二种:
1、一个对象可以通过成员函数(参数为指向同类的指针,引用,或者对象本身)访问另一对象的private变量。代码如下:

 1 #include<iostream>
 2 using namespace std;
 3 
 4 class A{
 5     public:
 6         int i;
 7         A():i(10),j(20){}
 8         void print( A * p){
 9             p->j = 50;
10             cout<<"私有变量p->j= "<<p->j<<endl;
11         }
12     private:
13         int j;
14 };
15 
16 int main()
17 {
18     A a;
19     A b;
20     a.print( &b);//这种是通过成员函数访问同一个类的private成员变量,
21                      //这种方式也可以修改对应对象所指向的private变量的值 
22 }
View Code

结果:

2、一个对象不可以通过成员函数(参数为指向异类的指针)访问另一异类对象的private变量。代码如下:

 1 #include<iostream>
 2 using namespace std;
 3 //class B;
 4 class B{
 5     private:
 6         int k;
 7     public:
 8         B():k(90){}
 9 }; 
10 class A{
11     public:
12         int i;
13         A():i(10),j(20){}
14         void print( A * p){
15             p->j = 50;
16             cout<<"p->j= "<<p->j<<endl;
17         }
18         void print( B*p){
19             p->k = 1;
20             cout<<"p->k= "<<p->k<<endl;
21         }
22     private:
23         int j;
24 };
25 
26 int main()
27 {
28     A a;
29     A b;
30     B c;
31 //    a.print( &b);//这种是通过成员函数访问同一个类的private成员变量,这种方式也可以修改对应对象所指向的private变量的值 
32     a.print(&c);//不同的类之间就不可以访问 
33 }  
View Code

上述代码在编译的时候出现下面的错误:
[Error] 'int B::k' is private

补充:

还需要补充的一点就是,这仅仅是在编译的时候有效的,如果有办法在运行时刻去修改private的成员变量也是可以的。
比如将一个类对象的指针强制转化成下面形式:
A a;
int* p = &a; //这里的a是A类的对象
*p = 20; //这样通过修改地址处的值进而修改类的成员变量
条件: (p 指向的地方恰好是在类中private成员变量所在的位置,因为一个类就是占用了一块内存,所有的成员变量都是依照次序顺序存储的,所以只要获得了类对象的基指针,再知道private成员变量的偏移量就可以在运行的时刻来修改private的值了)
通过上面那种方式就可以修改了private成员变量的值
说明:C++的OOP思想仅仅在源代码里存在(编译成功之前),编译之后的编码就不具有OOP思想了
(也就是说编译器作为规则来限制代码的OOP,但是编译后的.o文件与 C编译后的.o是一样的,都是就变成了过程式)
所以才有了只要在运行时刻能够拿到指针,就可以修改指针指向的内容。

原文地址:https://www.cnblogs.com/newneul/p/7657940.html