C++ 中作为基础 class 的单例模板
singleton template as base class in C++
根据C++ Singleton design pattern我写了一个单例模板
template <typename T>
class Singleton
{
public:
static T& getInstance()
{
static T instance;
return instance;
}
protected:
Singleton() {}
~Singleton() {}
public:
Singleton(Singleton const &) = delete;
Singleton& operator=(Singleton const &) = delete;
};
然后写了一个Logger单例(第一个)
class Logger // not derived Singleton<Logger>
{
friend class Singleton<Logger>;
private:
Logger(){};
~Logger(){};
public:
void print(void){std::cout << "hello" << std::endl;}
};
int main(void)
{
Singleton<Logger>::getInstance().print(); // use Singleton<Logger>
return 0;
}
但我也可以(第二个)
class Logger:public Singleton<Logger> // derived Singleton<Logger>
{
friend class Singleton<Logger>;
private:
Logger(){};
~Logger(){};
public:
void print(void){std::cout << "hello" << std::endl;}
};
int main(void)
{
Logger::getInstance().print(); // use Logger
return 0;
}
那么我的问题是
- 我的单例模板正确吗?
- 如果单例模板正确,则两个 Logger 都是正确的?
- 第一个和第二个的区别,哪个更好?
更新
在回答之后,我了解到第一个允许有多个记录器并且 singleton
class 似乎 unneeded.SO 我 discard 第一个。
关于第二个,我 省略了 析构函数,然后编译器将生成一个默认的内联 public 析构函数。这样看起来更简洁高效。
class Logger:public Singleton<Logger> // derived Singleton<Logger>
{
friend class Singleton<Logger>;
private:
Logger(){};
public:
void print(void){std::cout << "hello" << std::endl;}
};
1)你的单例模板是正确的。
2) 你的两个记录器都是正确的。但第二个是不好的做法。因为没有必要从单例模板派生记录器。
您可以通过将此行放在第二行来检查它:
Singleton<Logger>::getInstance().print();
工作正常。
3)第一个更好
- Is my singleton template correct?
是的。
- If singleton template is correct, the both Logger is correct?
由于复制构造函数,您的第一个代码段允许有多个记录器。
所以在这方面,是不正确的。
- The difference between the first one and the second one, which one is better?
如果您修复第一个片段以禁止也复制构造函数,那么您只会错过基本的 getInstance
而您的 Singleton
class 似乎不需要。
对于第二个代码段,您甚至可以省略析构函数。
根据C++ Singleton design pattern我写了一个单例模板
template <typename T>
class Singleton
{
public:
static T& getInstance()
{
static T instance;
return instance;
}
protected:
Singleton() {}
~Singleton() {}
public:
Singleton(Singleton const &) = delete;
Singleton& operator=(Singleton const &) = delete;
};
然后写了一个Logger单例(第一个)
class Logger // not derived Singleton<Logger>
{
friend class Singleton<Logger>;
private:
Logger(){};
~Logger(){};
public:
void print(void){std::cout << "hello" << std::endl;}
};
int main(void)
{
Singleton<Logger>::getInstance().print(); // use Singleton<Logger>
return 0;
}
但我也可以(第二个)
class Logger:public Singleton<Logger> // derived Singleton<Logger>
{
friend class Singleton<Logger>;
private:
Logger(){};
~Logger(){};
public:
void print(void){std::cout << "hello" << std::endl;}
};
int main(void)
{
Logger::getInstance().print(); // use Logger
return 0;
}
那么我的问题是
- 我的单例模板正确吗?
- 如果单例模板正确,则两个 Logger 都是正确的?
- 第一个和第二个的区别,哪个更好?
更新
在回答之后,我了解到第一个允许有多个记录器并且 singleton
class 似乎 unneeded.SO 我 discard 第一个。
关于第二个,我 省略了 析构函数,然后编译器将生成一个默认的内联 public 析构函数。这样看起来更简洁高效。
class Logger:public Singleton<Logger> // derived Singleton<Logger>
{
friend class Singleton<Logger>;
private:
Logger(){};
public:
void print(void){std::cout << "hello" << std::endl;}
};
1)你的单例模板是正确的。
2) 你的两个记录器都是正确的。但第二个是不好的做法。因为没有必要从单例模板派生记录器。 您可以通过将此行放在第二行来检查它:
Singleton<Logger>::getInstance().print();
工作正常。
3)第一个更好
- Is my singleton template correct?
是的。
- If singleton template is correct, the both Logger is correct?
由于复制构造函数,您的第一个代码段允许有多个记录器。 所以在这方面,是不正确的。
- The difference between the first one and the second one, which one is better?
如果您修复第一个片段以禁止也复制构造函数,那么您只会错过基本的 getInstance
而您的 Singleton
class 似乎不需要。
对于第二个代码段,您甚至可以省略析构函数。