使用指针在类外修改类的私有变量

类的私有变量在类外是不能访问的,但是这种保护机制仅仅是在编译器编译阶段来检查的,和const是一样,通过指针,我们还是可以访问并且修改的,因为一个类的对象仅仅包括自己的成员数据,所有的成员函数和静态成员变量都是一个实体,该类的所有对象共享这个实体,因此对象的长度是该类所有auto变量的长度,如果该类或者其基类有虚函数,生成的对象还要加上虚函数表的指针的大小,就是vptr的大小,4个字节。关于虚函数和虚函数表,可以参看http://blog.csdn.net/xie376450483/archive/2010/10/25/5964345.aspx

 

数据成员在对象中的排列顺序和类声明时候的数据的先后顺序一样,对应着内存分布,如果是多重继承,顺序和继承的先后顺序有关。其数据分布不做过多解释。

这样我们可以在类外使用一个类对象指针,然后通过指针修改来获取他的成员地址,进而修改其值

参看Demo

#include<iostream> using namespace std; class A { private: int num; char ch; //内存对齐的原因,所以下一个Num1的值是ch的地址+4 public: int num1; A(int , char,int); void fun(); }; A::A(int i,char c,int j) { num=i; ch=c; num1=j; } void A::fun() { cout<<"num="<<num<<endl; cout<<"ch ="<<ch<<endl; cout<<"num1="<<num1<<endl; char *q; int *ptr; ptr=&(this->num); cout<<"num在类中的地址"<<*((long *)&ptr)<<endl; q=&(this->ch); cout<<"ch在类中的地址"<<*((long *)&q)<<endl; ptr=&(this->num1); cout<<"num1在类中的地址"<<*((long *)&ptr)<<endl; } void main() { A a(5,'M',6); cout<<"修改对象a之前:"<<endl; a.fun(); A *p=&a; int *ptr=(int *)p; //修改指针类型 *ptr=*ptr+10; char *ptr1=(char *)ptr; ptr1=ptr1+4; //移动到ch的位置处 cout<<"在类外获取私有变量ch的地址"<<*((long *)&ptr1)<<endl; *ptr1='N'; ptr1=ptr1+1; //这样写对么?其实是错误的! ptr=(int *)ptr1; cout<<*((long *)&ptr)<<endl; *ptr=*ptr+20; cout<<"修改对象a之后"<<endl; a.fun(); }

运行结果如下

刚开始我也纳闷为什么num1的值没有修改,不是应该是26么?

哦,原来我忽略了内存对齐!找到原因后我们修改ptr1=ptr1+4;运行结果就正确了

 

你可能感兴趣的:(c,编译器,fun,2010)