高博的《视觉SLAM十四讲》中,project里的Config类,很好的示范了单例模式的实现与static静态成员的使用
每天早上起床拜一拜高博~
Config类是为了设置配置文件,并且从配置文件中读取预设的参数值。
由此,不难理解,在整个程序运行过程中最多只允许Config类有一个对象(只能有一个配置文件),所以使用单例模式
单例模式的实现,参考http://blog.csdn.net/hackbuteer1/article/details/7460019
在Config类的实现方法就是:1 构造函数设为private成员; 2 使用一个静态全局指针来保存单例; 3 类内一个public成员函数来访问该指针
上代码
config.h:
class Config
2 {
3 private:
// static 全局指针,在此处定义,但是一般不在类内初始化
4 static std::shared_ptr<Config> config_;
5 cv::FileStorage file_;
6
7 Config () {} // 构造函数是私有成员
8 public:
9 ~Config(); // 析构函数,关闭已打开的文件
10
11 // 设置配置文件 ,static 静态成员
12 static void setParameterFile( const std::string& filename );
13
14 // 模板函数,读取配置文件中的参数值
15 template< typename T >
16 static T get( const std::string& key )
17 {
18 return T( Config::config_->file_[key] );
19 }
20 }
头文件中定义的数据成员 static std::shared_ptr<Config> config_; 还有成员函数static void setParameterFile( const std::string& filename );都是静态成员,表示他们不是属于对象的成员,
而是属于整个类的。
静态数据成员并不是在类创建对象的时候定义和初始化,因此肯定不能在构造函数中初始化。而且一般不在类内初始化,相反,必须放到类的外部定义和初始化。
也就是下面config.cpp文件中的最后一句。
类似于全局变量,静态数据成员定义在所有函数之外,因此一旦被定义就存在程序的整个生命周期之中。
定义静态数据成员的方法就和在类外定义成员函数差不多,需要指定类型名sharedPtr<Config>(智能指针类型),类名Config,作用域运算符::,以及成员的名字 config_
-- 摘自c++primer
config.cpp:
void Config::setParameterFile( const std::string& filename )
{
if ( config_ == nullptr )
config_ = shared_ptr<Config>(new Config);
config_->file_ = cv::FileStorage( filename.c_str(), cv::FileStorage::READ );
if ( config_->file_.isOpened() == false )
{
std::cerr<<"parameter file "<<filename<<" does not exist."<<std::endl;
config_->file_.release();
return;
}
}
Config::~Config()
{
if ( file_.isOpened() )
file_.release();
}
shared_ptr<Config> Config::config_ = nullptr;