C++ class singleton pattern

Basic singleton pattern (hungry man style, lazy man style)

lazy mode

懒汉模式是一种单例模式的实现方式,其特点是在首次请求获取单例实例时才进行实例化,以达到延迟加载的效果。

在懒汉模式中,通常会将构造函数设置为私有,以确保只能通过类的静态方法来获取实例。同时,为了保证实例只被创建一次,可以在静态方法中使用静态局部变量来保存单例实例。当静态方法被调用时,会首先检查静态局部变量是否已经被初始化,如果没有,则进行实例化操作,然后返回实例。

懒汉模式的优点是可以实现延迟加载,避免了在程序启动时就创建实例的开销,从而提高了程序的启动速度。然而,由于懒汉模式需要在运行时进行实例化,所以可能会在多线程环境下存在线程安全问题,需要采用线程安全措施来保证单例实例的正确性。同时,由于在每次获取实例时都需要进行线程同步的操作,所以懒汉模式的效率可能会受到一定的影响。

Template…lazy mode

class Singleton {
    
    
public:
    // 获取单例实例的静态函数
    static Singleton& getInstance() {
    
    
        // 使用静态局部变量确保只被初始化一次
        static Singleton instance;
        return instance;
    }

    // 假设有一些其他的公共方法...
    void doSomething() {
    
    
        // ...
    }

private:
    // 将构造函数声明为私有,确保只有这个类内部可以创建实例
    Singleton() {
    
    }
};

// 使用单例模式获取实例
Singleton& s = Singleton::getInstance();
s.doSomething();

example

#include <iostream>

using namespace std;

// 定义 SumCalculator 类
class SumCalculator {
    
    
public:
    // 获取 SumCalculator 的单例实例
    static SumCalculator& Get()
    {
    
    
        // 定义静态局部变量,确保只初始化一次
        static SumCalculator instance;
        return instance;
    }

    // 计算从 start 到 end 的整数和
    int Calculate(int start, int end) {
    
    
        int sum = 0;
        for (int i = start; i <= end; i++) {
    
    
            sum += i;
        }
        return sum;
    }

private:
    // 私有化构造函数,确保只能通过 Get 函数获取实例
    SumCalculator() {
    
    }
};

// 主函数
int main() {
    
    
    // 获取 SumCalculator 的单例实例模式
    SumCalculator& calculator = SumCalculator::Get();

    // 计算从1到100的和
    int sum = calculator.Calculate(1, 100);

    // 输出结果
    cout << "The sum from 1 to 100 is: " << sum << endl;

    return 0;
}



Hungry Chinese style

这是饿汉式单例模式的一种实现方式,它在类定义中直接定义了一个静态 Singleton 对象 instance,并在类外部进行了初始化。因此,在程序启动时就会创建该对象,因此被称为“饿汉式”,因为对象实例在使用之前就已经“饿了”。

注意,这种实现方式也是线程安全的,因为静态变量的初始化是线程安全的。然而,在某些情况下,这种实现方式可能会浪费一些资源,因为对象实例在程序启动时就已经创建了,即使在程序运行的早期阶段可能并没有用到它。

class Singleton {
    
    
public:
    // 获取单例实例的静态函数
    static Singleton& getInstance() {
    
    
        // 定义一个静态成员变量作为实例,并在第一次调用时初始化
        static Singleton instance;
        return instance;
    }

    // 假设有一些其他的公共方法...
    void doSomething() {
    
    
        // ...
    }

private:
    // 将构造函数声明为私有,确保只有这个类内部可以创建实例
    Singleton() {
    
    }
};
Singleton Singleton::instance;


#include <iostream>

using namespace std;

class Random {
    
    
public:
    Random(const Random &) = delete;

    static Random &Get() {
    
    
        return s_Instance;
    }

    static float Float(){
    
     return Get().IFloat();}
private:
    float IFloat() {
    
     return m_RandomGenerator; }
    Random() {
    
    }

    float m_RandomGenerator = 0.5f;
    static Random s_Instance;
};

Random Random::s_Instance;

int main() {
    
    


    float num = Random::Float();
    cout << num << endl;

}

Summarize

The lazy mode and the hungry mode are both implementations of the singleton mode.

The lazy mode creates an instance when the instance is obtained for the first time, so it is also called lazy loading mode. The advantage is that it saves memory space, but the disadvantage is that thread safety issues need to be considered in a multi-threaded environment, and locking is required to ensure that only one thread creates an instance. In addition, since the instance is created only when it is used for the first time, it is necessary to determine whether the instance already exists before using it multiple times, which may affect program performance.

The Hungry-style mode creates an instance when the program starts, so it is also called the preloading mode. The advantage is that it is simple to implement, thread-safe, and can avoid problems such as competition and locking in a multi-threaded environment. The disadvantage is that it may waste some memory space, because the instance has been created when the program starts, but it may be lost during program execution. Has not been used.

Therefore, when choosing between lazy mode and hungry mode, you need to choose based on specific scene needs and performance requirements.

Guess you like

Origin blog.csdn.net/qq_38156743/article/details/130341585