zoukankan      html  css  js  c++  java
  • 访问C++类对象中私有成员变量的方法

    原则上,C++类中私有变量不允许在类之外的其他任何地方访问,一般来说功能完善的类都会提供get,set方法来操作类属性值,但如果没有getset方法都没有提供,比如使用的是第三方提供的.o(或者动态库)来进行开发的,并且实际应用中我们确确实实需要改变其中某个对象的一个私有参数,有没有什么办法呢?我们知道,一个进程有程序段和数据段,如果我们知道了对象的数据空间,那么得到该对象的成员变量值也就很简单了,而实际上,对象数据段的首地址其实就是对象地址,以例子说明:
    class A
    {
    public:
       int i;
       bool setJ(int _j){j = _j;};
       int getJ() const {return j;};
    private:
       int j;
    };

    int main()
    {
        A a;
       printf("a's address is %u.n",&a); //
     打印对象a的地址
       printf("a.i's address is %u.n",(&(a.i))); //
     打印对象a的成员变量i的地址
    }

    执行上面程序,可以看到结果,两个值时一样的,也就是说明对象地址就是第一个成员变量的地址。
    我们知道,C++编译器将数据和程序段分开,所有的类变量会按照声明顺序依次存入数据段,所以,如果知道了第一个变量的地址,那么后面的地址也就依次累加即可逐一求出了。有了变量地址,那么也就可以对它的值进行修改了。还是以上面的例子来说明,一下程序编写了如何更改类成员b的值:

    int main()
    {
        A a;
        a.setJ(2);
        printf("before modified:the member j of a is %d.n",a.getJ()); //
     打印j的值。
        int *p = (int *)(int(&a) + sizeof(a.i));
        *p = 10;
        printf("after modified:the member j of a is %d.n",a.getJ()); //
     打印j的值。
    }

    可以得出此时j成员变量的值由2变成10了。

    总结:直接对地址空间操作,请小心为妙。。。

     

    此外,另附一篇与此类似的文章,也很有启发性。

    分析程序员和黑客的区别 
    题目: 
      设有如下C++ 

    class A
    {
      int value;
    public:
      A(int n = 0) : value(n) {}
      int GetValue()
      {
        return value;
      }
    };


      请使用某种方式来在类的外部改变私有成员A::value的值。 
    程序员的可能做法: 


    class A
    {
      int value;
    public:
      A(int n = 0) : value(n) {}
      int GetValue()
      {
        return value;
      }
      void SetValue(int n)
      {
        value = n;
      }
    };
    void f()
    {
      A a;
      a.SetValue(5);
    }

    黑客的可能做法: 


    void f()
    {
      A a;
      *((int *)&a) = 5;
    }

      结论: 
      程序员习惯于遵循既有的限制来增加既有的东西。 
      黑客习惯于利用既有的东西来打破既有的限制。

  • 相关阅读:
    排序算法对比,步骤,改进,java代码实现
    OracleJDK与OpenJDK的区别和联系
    C++函数中那些不可以被声明为虚函数的函数
    编码实现环状单向链表(尾指针直接指向头指针,中间没有空节点),去除连续的重复元素的操作。
    大华2014校园招聘面试题链式存储串的连接操作
    线性表可用顺序表或链表存储的优缺点
    豆瓣面试题strstr)
    百度2014校园招聘消除嵌套的括号
    Wireshark基本介绍和学习TCP三次握手(转载)
    据说是淘宝面试题“给定一个数组将大于0的放在最右边,等于0的放在中间,大于0的放在最左边”
  • 原文地址:https://www.cnblogs.com/wwb0111/p/3098967.html
Copyright © 2011-2022 走看看