检查C++类私有变量的方法

前言

C++的封装是个好东西,将需要保护的数据成员定义为私有成员可以有效的防止这些数据没有意外修改,但是在程序release之前,良好的封装却成为我们调试的代码的障碍,特别是在没有IDE的情况下面。

在Linux环境下,我没有使用IDE的习惯,也不熟悉配置使用gdb,感觉就是很麻烦,因此我的调试方法就是printf/cout。直接编写调试的输出信息的代码,感觉灵活性更强,但是带来的后果就是,原始的程序代码被大量调试代码,导致代码的严重整洁性和可读性下降。

为了检查C++类中的私有数据,同时又保证尽量少的修改原有的类文件代码,我想了一个不算很好,但是也能基本上完成目标的方法。

思路

分析上面的需求,我自己设定我的目标有三个:

  1. 能够在类外访问类的私有成员变量
  2. 不用修改或是很小的修改原有类代码
  3. 调试模块对所有类通用

对于目标第一点,比较好实现,只要用指针或者引用记录类私有成员就可,不过要注意记录的指针或者引用不能修改其私有成员。

对于第二点,我实在想不出有什么方法,能够在完全不修改类代码的前提下,就能获取到它其中内部私有数据成员的地址的方法,所以我只能选择增加少量代码,负责记录类的私有数据成员。

对于第三点,我可以将这个功能模块写成一个调试类,限定这个只负责记录信息,而将具体的显示打印交给使用者。

代码

于是我使用不到40行的代码完成了我想法,代码如下:

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
#include <map>
#include <string>
using namespace std;

class ClassDataMonitor
{
public:
template <typename T>
const T& get_elem_by_name(string name, T smp)
{
return (T*)data_map[name];
}
bool is_elem_monitored(string name)
{
if(data_map.find(name) != data_map.end())
return true;
else
return false;
}

void add_data_monitoring(string name, char *data_addr)
{
data_map[name] = data_addr;
}
private:
map<string, char*> data_map;
};

以上我使用map来记录类中数据成员的一对信息:名字和地址,在使用时我们通过名字引索找的数据成员的地址。

另外get_elem_by_name函数返回是一个常引用,保证传出的数据不会被修改。而它的参数是数据成员的名字和类型。可以看到我了使用模板,指定一个类型,所以我可以通过char *的地址指针,转为实际类型的变量,使我可以返回该类型的常引用。

使用

在使用时,可以有两种方法添加数据监视,一是让被监视的类继承ClassDataMonitor,二是让ClassDataMonito的对象成为被监视类的共有成员。完成上步操作后还是要在被监视类中添加代码,指定监视的数据成员,如下:

1
add_data_monitoring("data1", (char*)&data1);

这个类能够帮助我在类外,也能够随时查看其中的私有变量的值,虽然不够直接,但是至少是实现了功能,可惜是它不能在不修改原来类的情况下使用。

Compartir