zoukankan      html  css  js  c++  java
  • (笔记):组合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是一样的,都是就变成了过程式)
    所以才有了只要在运行时刻能够拿到指针,就可以修改指针指向的内容。

  • 相关阅读:
    #Laravel 笔记# 多语言化 App::setLocale() 持久化。
    thinkphp 3.2 发送邮件(Phpmailer)
    深度学习的注意力机制
    图像检索引擎vearch安装与测试使用
    word2vector
    GPU环境搭建
    ImportError: libSM.so.6: cannot open shared object file: No such file or dir
    shell中&&和||的用法
    Linux 远程连接sftp与ftp
    mysql-connector-java各版本及与mysql、JDK版本的对应
  • 原文地址:https://www.cnblogs.com/newneul/p/7657940.html
Copyright © 2011-2022 走看看