C++单例模式
C++ singleton pattern
考虑以下来自yolinux的singleton模式的设计(http://www.yolinux.com/TUTORIALS/C++Singleton.html)
#include <string>
class Logger{
public:
static Logger* Instance();
bool openLogFile(std::string logFile);
void writeToLogFile();
bool closeLogFile();
private:
Logger(){}; // Private so that it can not be called
Logger(Logger const&){}; // copy constructor is private
Logger& operator=(Logger const&){}; // assignment operator is private
static Logger* m_pInstance;
};
有人能解释一下为什么这里需要Logger(Logger const&){};
和Logger& operator=(Logger const&){};
吗
提前谢谢。
如果强制复制构造函数和赋值运算符为私有运算符,则无法编译两个Logger对象的赋值。
这将导致链接器错误,该错误不是显式消息。这些方法是默认生成的,所以你必须强制它们是私有
在C++11中,他们使用删除的方法来获得更清晰的消息
Logger(Logger const&)=delete; // copy constructor does not exist
Logger& operator=(Logger const&)=delete; // assignment operator does not exist
删除不是强制性的,单例在没有这个功能的情况下也能很好地工作,所以如果你的编译器不支持这个功能,你可以把它设为私有的,它也能工作。此功能提供明确的错误消息,但不会影响单例本身的行为。
有关删除功能的更多信息,您可以在这里查看:
=函数声明后删除的含义
您还可以通过将析构函数设为私有来防止对象被销毁。
将析构函数设为私有函数有什么用?
从您的链接:
This design pattern and methodology ensures that only one instance of the C++ class is instantiated.
Logger(Logger const&)
是一个允许复制对象的复制构造函数。这是错误的想法。Logger& operator=(Logger&)
还允许复制对象。
注释很好地解释了这一点。
如果您没有显式定义构造函数和复制构造函数,那么它们将默认创建为公共构造函数。通过在这里定义它们,您可以确保它们是私有的,因此永远不会被用户调用。
复制构造函数和左值赋值运算符被声明为私有,以使类型不可复制。
另一方面,我鼓励您使用Meyers单例,而不是基于动态内存的:它更容易实现,不会泄漏(请注意,严格来说,您的单例会泄漏内存,实例永远不会被删除),并且是C++11标准内存模型中定义的线程安全的:
T& instance()
{
static T _instance;
return _instance;
}
它们是复制构造函数和复制赋值运算符。如果它们没有被定义为私有,它们将自动生成为公共实例,并且实例将是可复制的,这与Singleton模式相矛盾。
由于C++11标准,您也可以使用:
Logger(const Logger&) = delete;
Logger& operator=(const Logger&) = delete;
这种语法可能更清晰,也可以确保对象即使是朋友和私人成员也不能复制。
实现单例行为的传统解决方案是声明构造函数私有。复制构造函数和赋值运算符(故意没有实现)被声明为私有的,以防止任何类型的复制被制作为
•因为它们是私有的,这将导致任何试图使用它们但无法访问类的私有部分的人在编译时出错。
•这会让朋友(和类本身)在链接时(如果你在那里检查了这些)或很可能在运行时(试图加载库时)以未定义符号的形式出现错误。
- C++单例模式代码无法运行,不知道为什么?
- 工厂模式和单例模式:未定义的引用
- 使用静态和避免单例模式声明全局变量
- 如何在 c++ 中使用单例模式时编写 cmake 文件
- 可派生类的单例模式
- 这是单例模式的正确实现吗?
- 懒惰的初始化使用单例模式
- 带参数的单例模式对象
- 另一个类上使用的单例模式
- 这是单例模式的示例吗?
- 了解单例模式中的操作重载
- 为什么我们在C++的单例模式中使用静态方法和静态函数
- 强制单例模式的静态函数
- 当周围有线程时,创建类的许多实例会失败吗?- 单例模式
- 为什么这种单例模式不起作用?
- 这种c++单例模式和方法公开是一种好的实践吗?
- c++单例模式_实现和内存管理
- 单例模式实现错误
- c++日志器的单例模式
- 单例模式:auto_ptr和unique_ptr的不同行为