说单例就要把初始化参数写死到类里面。那么我们来举一个例子。
比如我们有一个INI读写类,因为读写同一个文件,那做成单例肯定有好处,不会多个实例访问。代码如下:
class Config : public QObject{
public:
// 单实例
static Config& i();
void save(const QString &key,const QVariant &value);
};
// 基本没问题,单例就用上面的方法创建:
Config &Config::i(){
static Config cfg();
return cfg;
}
Config::Config() : QObject(nullptr){
m_configFile0 = new QSettings("c:\\abc.ini",QSettings::IniFormat);
// 解决中文乱码问题
m_configFile0->setIniCodec(QTextCodec::codecForName("UTF-8"));
}
看到没,这个扛精他把文件写到构造函数类里面,文件为c:\\abc.ini。
也就是说,他这个Config类,移植到别的工程的时候,都要改一下这个文件名,才能起一个新名字。当然他也可以起一个唯一的跟程序绑定名字,目录也可以放到temp,这又是牛角尖,我们不说。
假如他是负责这个模块,然后这个模块,比如dll,要给别的exe工程用,那是不是每个exe都要一个不同的dll?他还没发现他在做重复工作是不是?svn一大堆重复的Config工程?
那我们变通下:
class Config : public QObject{
public:
// 单实例,增加参数
static Config& i(QString file="");
void save(const QString &key,const QVariant &value);
};
Config &Config::i(QString file){
static Config cfg(file);
return cfg;
}
// 构造时增加参数
Config::Config(QString file) : QObject(nullptr){
m_configFile0 = new QSettings(file,QSettings::IniFormat);
// 解决中文乱码问题
m_configFile0->setIniCodec(QTextCodec::codecForName("UTF-8"));
}
如上所述,这个dll首次构造时是可以带一个参数进去的,就是可以把配置文件路径传进去,后续访问是不需要的。
这样,这个dll只需要维护一份,就可以配形形色色的exe了。