Search This Blog

Tuesday, September 26, 2006

避免全局变量

全局变量是方便,但是在多线程/进程环境下是不安全的,所以在有潜在多线程/进程应用的情况下应该尽量避免全局变量。事实上,全局变量也不利于程序的模块化。
举个例子,一个自己遇到的小问题。
我有一个结构体:
typedef struct _gtalk_user{
gtalk_user_data_ptr gudp;
gtalk_buddy_ptr gbp;
gtalk_connection_ptr gcp;
gtalk_handlers_ptr ghp;
XML_Parser parser;
int errorno;

}gtalk_user;

结构体的成员包括了四个结构体指针,一个expat的解析器,还有一个错误号变量,这个程序可以让用户选择是否进行tls连接,所以gudp->use_tls是根据用户的输入赋值的,这相当于一个用户的偏好,而事实上真正要用到这个值的是在连接的时候。由于某种原因,我不想让网络连接的模块知道gtalk_user里除gcp以外的信息,又不想让调用网络连接模块里的函数的用户知道gtalk_user里的信息,难道只能把use_tls声明为全局变量吗?
我是这么做的:
void gtalk_connection_init (gtak_user_ptr)是连接初始化函数,这是对外的接口,而事实上我把它定义成了
#define gtalk_connection_init(gup) _connection_init(gup->gcp,gup->gudp->use_tls)
真正办实事的函数_connection_init的原型为
void _connection_init (gtalk_connection_ptr gcp,int use_tls);
这样,对于用户来说,只管对gup所代表的gtalk_user这个抽象的对象调用gtalk_connection_init函数,它不需要了解gtalk_user内部的细节
对于_connection_init函数来说,它也不需要了解gcp以外的信息。
其实质是我用宏定义把给_connection_init函数传递use_tls参数的过程对用户屏蔽了,于是达到了我的目的。

一点体会,有错误欢迎指正。

No comments: