KS04-19 用单体模式实现全局配置
本帖最后由 baizy77 于 2019-8-30 14:55 编辑该文章原创于Qter开源社区(www.qter.org)作者: 女儿叫老白转载请注明出处!---------------------------------------------------------------------------------------------------------------------
[*]【独家连载】《Qt入门与提高-GUI产品开发》目录
[*]网页版课程源码 提取码:1uy7
[*]免费版视频教程
----------------------------------------------------------------------------------------------------------------------
引言---------------------------------------------------------------- 在很多人共同开发一个软件项目时,大家会分别负责不同的模块开发,最后把这些模块拼接成一个完整的程序。很多情况下,这些模块之间需要共享一些配置数据。这时,可能有人首先想到了全局变量。全局变量的确也能达到目的,但是我们有一个更好的选择,就是采用设计模式中的单体模式。本节,我们为朋友们介绍一下单体模式实现全局配置的方法。
正文---------------------------------------------------------------- 单体模式(Singleton),顾名思义,指的是只有一个实体。那么怎样做才能让配置只有一个实体呢? 在本节示例代码中,我们的保存配置信息的类为CConfig。为了实现单体模式,我们需要把CConfig做一下改造:把构造函数、析构函数、拷贝构造函数声明为私有成员:代码清单04-19-01config.hclass KS04_19_CONFIG_Export CConfig {
// ……
private:
/**
* @brief构造函数,定义为私有的目的是防止他人使用该类构造对象。
* @return 无
*/
CConfig() { }
/**
* @brief拷贝构造函数,定义为私有的目的是防止编译器调用默认的拷贝构造
* 函数隐式构造该类的对象。
* @return 无
*/
CConfig(const CConfig&);
/**
* @brief析构造函数,定义为私有的目的是防止他人用delete语句删除单体对象。
* @return 无
*/
~CConfig(){}
};
代码清单04-19-01中:在第3~8行,为了保证该类对象只有一个实体存在,我们将构造函数声明为私有的,目的是防止他人使用该类构造对象(如果将类的构造函数声明为私有,则new CConfig这种代码将会被编译器报错,因为编译器无法调用私有的构造函数来构造对象,只能调用public的构造函数)。我们将析构函数声明为私有,目的是防止他人用delete语句删除我们构造的单体对象。另外,我们将拷贝构造函数也声明为私有,目的是防止编译器调用默认的拷贝构造函数隐式构造该类的对象。好了,把所有能够构造对象的入口封住之后,我们来创建自己的接口来构造单体对象,方法如下,为CConfig添加一个私有成员:代码清单04-19-02config.hclass KS04_19_CONFIG_Export CConfig {
// ......
public:
static CConfig& instance();
private:
static CConfig s_config; /// 配置对象实例
// .....
};
代码清单04-19-02中:在第6行,定义了一个私有的static成员对象。朋友们看到了吗?这个私有成员的类型就是CConfig。请注意,此行代码并不能构造该s_config对象,我们需要单独对其进行构造:代码清单04-19-03config.cpp:CConfig CConfig::s_config;
CCfonfig::CConfig(){
//......
}
代码清单04-19-03中:第1行的代码表示构造该s_config对象。
回到代码清单04-19-02:在第4行,提供一个static接口用来访问该静态对象。该接口实现如下:代码清单04-19-04config.cppCConfig& CConfig::instance() {
return s_config;
}
代码清单04-19-04中:该接口的实现比较简单,直接返回之前定义的static对象即可。
到此为止,单体类定义好了。那么该怎么使用单体类呢?其实很简单。方法就是使用static接口的调用语法,如下代码将得到该单体对象的引用:CConfig::instance()比如,在本节示例代码中,我们在dll中调用该单体对象的接口设置参数:代码清单04-19-05model.cpp
bool CModel::initialize() {
CConfig::instance().setSelectRadius(3.f);
return true;
}
代码清单04-19-05中;第2行,通过CConfig::instance()静态接口得到单体对象的引用,然后调用其setSelectRadius()接口。然后,我们在exe中调用该单体对象的接口获取刚刚设置的参数:代码清单04-19-06mian.cpp
int main(int argc, char * argv[]) {
CModel model;
model.initialize();
qreal r = CConfig::instance().getSelectRadius();
cout << "r = " << r << endl;
return 0;
}
结语----------------------------------------------------------------在本节中,我们介绍了通过单体模式实现全局配置的方法。在设计单体类时,需要注意的是下面几点: 1). 将构造函数、析构函数、拷贝构造函数声明为私有成员。拷贝构造函数可以只定义不实现。 2). 为单体类添加一个static成员变量,类型为该单体类。在cpp中需要用以下语句进行定义:
CConfig CConfig::m_config; 3). 为单体类添加一个static成员接口,比如instance(),该接口无参数,返回类型为类的引用或类指针,该接口内部返回static成员变量的引用或指针。 4). 如果在静态接口instance()内部构造一个static对象并返回该对象的引用,那么建议使用全局锁保护该static对象。如果作为类的成员变量,则不需要用锁保护(如果是指针类型的成员变量,则需要用锁进行保护)。 5). 该单体对象的使用方法是通过类的static接口instance():CConfig::instance()好了,朋友们可以练习一下编写自己的单体类啦。
课程目录: 《Qt入门与提高-GUI产品开发》目录
上一节:KS04-18 类的二进制格式序列化-向前兼容下一节:KS04-20 用流方式读写XML
页:
[1]