总所周知,在OOP编程中,类的私有成员是不让访问的.今天我们就来解开c++类私有成员的面纱,利用指针的手段实现其访问.

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream>
using namespace std;
class Dog
{
public:
void SayAddress()
{
cout<<"address of age: "<<&age_<<endl;
cout<<"address of heigh: "<<&heigh_<<endl;
cout<<"address of name: "<<&name_<<endl;
}
// initialization list
Dog(string name,int age):name_(name),age_(age){}
string GetName(){ return name_;}
int GetAge(){ return age_;}
int GetHeigh(){ return heigh_;}
private:
int age_;
int heigh_;
string name_;
};
int main() {
Dog dog1("xiao huang",2);
cout<<dog1.GetAge()<<endl;
cout<<dog1.GetHeigh()<<endl;
cout<<dog1.GetName()<<endl;
int* p=(int *)&dog1;
cout<<p<<endl;
*p=5;
p++;
cout<<p<<endl;
*p=4;
p++;
cout<<p<<endl;
// must cast to pointer of string
*(string *)p="gou gou";
cout<<dog1.GetAge()<<endl;
cout<<dog1.GetHeigh()<<endl;
cout<<dog1.GetName()<<endl;
dog1.SayAddress();
return 0;
}

Error

1
no error

输出结果:

1
2
3
4
5
6
7
8
9
10
11
12
2
0
xiao huang
0x7fff369e9b60
0x7fff369e9b64
0x7fff369e9b68
5
4
gou gou
address of age: 0x7fff369e9b60
address of heigh: 0x7fff369e9b64
address of name: 0x7fff369e9b68

其实这不是面向对象设计的初衷,因为我们是不希望私有成员被访问的

Analysis

一句话可以解释这种非常规的使用:获取对象的地址,利用c++可以使用指针操作地址的特性,直接操作私有成员
关键是如何找到私有成员的地址,从代码可以知道,对象的地址其实和对象的成员变量的起始地址一样.但是我们如何找到私有函数的地址了?小编这儿也没有什么方法,因为这些都是黑客要干的事,我等只能望尘莫及了.

Summary

看上去很酷,不过这真不是程序员应该干的.这回使得我们的代码很难读.强烈建议,遵循OPP的原则写代码