• 利用指针突破C++编译器的防线


    C++ 面向对象的一大特性就是封装,使用不同的访问控制符来控制外接对其的访问权限。比如:

    1 class A
    2 {
    3     public:
    4         A(): i(10){}
    5         void print(){ cout << "A::i = " << i << endl; }
    6 
    7     private:
    8         int i;
    9 };

          这里的A 类对象的 i 对外接来说就是透明的。通过private 来隐藏对象的某些属性。但是,C++也继承了大部分C的特性,比如说很好很强大的指针。利用指针,我们可以绕过编译器做一些 见不得光的事情。虽然不建议这么做,因为这样不仅破坏了数据的封装特性,也会带来很多危险。不过这里我还是这么做了。。。。。

    请看下面的这个例子,利用指针p去修改 对象a 的私有成员i 的值:

     1 /*========================================================*
     2  *               利用指针突破C++编译器的防线
     3  *
     4  *                  樊列龙 2013/6/22
     5  *
     6 *========================================================*/
     7 
     8 #include <iostream>
     9 using namespace std;
    10 
    11 class A
    12 {
    13     public:
    14         A(): i(10){}
    15         void print(){ cout << "A::i = " << i << endl; }
    16 
    17     private:
    18         const int i;
    19 };
    20 
    21 int main()
    22 {
    23     A a;
    24 
    25     int* p = (int*)&a;           // 突破编译器的防线
    26     a.print();
    27 
    28     *p = 30;                     // 偷偷修改a 对象私有成员的值
    29     a.print();
    30 
    31     return 0;
    32 }

    执行结果:

    A::i = 10
    A::i = 30

    通过打印结果可以看出p 真的做了不该做的事情

    这时候有的朋友可能会觉得将A 类中的 i 声明成 const int 指针p应该就无能为力了吧。

    事实证明 私有成员变量及时是 const 类型也是无济于事的,他们都无法阻挡指针的穿透力!!!

    纯属娱乐,写代码的时候千万不要真的这么写!

  • 相关阅读:
    动态代理
    构建一个REST风格的Web服务(Building a RESTful Web Service)
    使用Spring Boot构建应用程序(Building an Application with Spring Boot)
    SpringBoot笔记 三
    SpringBoot笔记 一
    redis的linux安装
    mysql的windows安装
    linux下Redis安装
    上网列表
    shell每日发邮件
  • 原文地址:https://www.cnblogs.com/CocoonFan/p/3149231.html
Copyright © 2020-2023  润新知