C++的单例模式是一种常用的设计模式,用于确保一个类在应用程序中只存在一个实例,以及提供全局访问该实例的机制。
在C++的单例模式实现中,通常将单例类的构造函数设为私有的,以禁止其他代码直接构造其实例。然后,提供一个静态方法,用于获得该类的唯一实例。该方法将根据需要创建一个实例,并将其保存在静态成员变量中。每次调用该方法时,都会返回该唯一实例。这种实现方式的代码大致如下:
class Singleton {
private:
Singleton() {}
static Singleton *instance_;
public:
static Singleton *GetInstance() {
if (instance_ == nullptr) {
instance_ = new Singleton();
}
return instance_;
}
};
Singleton *Singleton::instance_ = nullptr;
但是,在上述实现方式中,必须在单例类中定义一个静态成员变量(如 instance_),用于存储唯一实例。这往往会在程序启动时初始化,而且即使在以后的程序运行中,它也会一直存在于内存中,浪费大量的内存空间。
因此,更好的实现方式是:
在 GetInstance() 函数中,将单例对象定义为静态局部变量。这样,仅在该函数首次被调用时,才会创建该对象。后续调用该函数时,就直接使用现有的实例了。
为避免一个潜在的问题,即在多个线程同时调用 GetInstace() 函数时,有可能会创建多个对象,并且这些对象可能在同一时间获取 instance_ 的值,从而导致程序错误。因此,应该使用双检锁机制或者不使用静态成员变量并手动管理实例内存。
示例1:使用静态局部变量实现单例模式
class Singleton {
private:
Singleton() {}
public:
static Singleton &GetInstance(){
static Singleton instance;
return instance;
}
};
示例2:使用双检锁机制实现单例模式
class Singleton {
private:
Singleton() {}
static Singleton *instance_;
static std::mutex mutex_;
public:
static Singleton *GetInstance() {
if (instance_ == nullptr) {
std::lock_guard<std::mutex> lock(mutex_);
if (instance_ == nullptr) {
instance_ = new Singleton();
}
}
return instance_;
}
};
Singleton *Singleton::instance_ = nullptr;
std::mutex Singleton::mutex_;
以上两个示例中,都只在需要时才会创建实例对象,从而避免了静态成员变量对内存空间的浪费。同时,示例2还加入了线程安全性保护措施,避免了多线程环境下出现的程序错误。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++单例模式为何要实例化一个对象不全部使用static - Python技术站