C++中访问控制

文章来源:http://blog.163.com/zhaoxin851055@126/blog/static/8112929820092514256782/

1 #include <iostream>
2 using namespace std;

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指针传入这个参数。于是就完成了对象与成员函数的绑定(或联系).
实例化后就得到同一个类的多个不同的对象,既然成员函数共享的,那么成员函数就可以操作对象的数据成员。
问题是现在有多个对象,成员函数需要知道操作的是哪个对象的数据成员?
比如有对象obj1obj2,都属于A类,A类有public成员函数foo()
如果obj1调用该函数,编译时会给foo函数传入this指针,obj1,foo中操作obj1自身的成员就不用任何修饰,直接访问,因为其中的数据成员自动根据this指针找到。
如果obj1调用该函数,同样可以访问同类的其他对象的数据成员!那么你需要做的是让foo函数知道是同类对象中哪个对象的数据成员,一个解决办法是传入同类其他对象的指针或引用,那么就可以操作同类其他对象的数据成员。
foo(A &obj)
这样定义,然后调用:
obj1.foo(obj2)
就可以在obj1访问obj2的数据成员,而无论这些数据成员是private还是protected

搬出C++ Object Model,可以画出各个对象的内存map就可以更清晰的看出:


总结:C++的访问修饰符的作用是以类为单位,而不是以对象为单位。

通俗的讲,同类的对象间可以互相访问对方的数据成员,只不过访问途径不是直接访问.
 骤是:通过一个对象调用其public成员函数,此成员函数可以访问到自己的或者同类其他对象的public/private/protected数据成 员和成员函数(类的所有对象共用),而且还需要指明是哪个对象的数据成员(调用函数的对象自己的成员不用指明,因为有this指针;其他对象的数据成员可 以通过引用或指针间接指明)

C++
public,protected,private访问小结
第一:private,public,protected方法的访问范围.public继承下)
private: 
只能由该类中的函数、其友元函数访问,不能被任何其他访问,该类的对象也不能访问
protected: 
可以被该类中的函数、子类的函数、以及其友元函数访问,不能被该类的对象访问 
public: 
可以被该类中的函数、子类的函数、其友元函数访问,也可以由该类的对象访问
注:友元函数包括两种:设为友元的全局函数,设为友元类中的成员函数

第二:类的继承后方法属性变化
使用private继承,父类的所有方法在子类中变为private; 
使用protected继承,父类的protectedpublic方法在子类中变为protected,private方法不变
使用public继承,父类中的方法属性不发生改变;

 

public:

protected:

private:

public继承

public

protected

---

protected继承

protected

protected

---

private继承

private

private

---


protected继承和private继承能降低访问权限

再次提到:可以提供访问行为的主语为函数
类体内的访问没有访问限制一说,即private函数可以访问public/protected/private成员函数或数据成员,同理,protected函数,public函数也可以任意访问该类体中定义的成员
public
继承下,基类中的publicprotected成员继承为该子类的publicprotected成员(成员函数或数据成员),然后访问仍然按类内的无限制访问

对于类域范围内,成员函数访问无所谓访问限制。
对于继承情况下的基类private成员,在派生类中仍然继承了下来,只不过它不能直接访问即使在类里也不行更不用说是类对象了。
可以通过下列例子看到:

1 #include <iostream>
2 using namespace std;
3 
4 class C{
5 public:
6      C(int val) : m_c(val) {}
7 private:
8     int m_c;
9 };
10 
11 class D: public C{
12 public:
13      D(int val1, int val2) : C(val1), m_d(val2) {}
14     int m_d;
15 };
16 
17 int main()
18 {
19 
20 
21      cout << sizeof(C) << " " << sizeof(D) << endl; // 4   8
22      D obj(2, 25);
23      cout << &obj << " " << &obj.m_d << endl; //0x0012FF78    0X0012FF7C
24     //cout << obj.m_