基于C++的单例模式

单例模式是一种设计模式.
单例模式表示在定义的某一个类中,只能有唯一的一个对象(即只能有一个实例).
优点:提高了封装性,外部不能轻易的改变实例.

饿汉模式

含义:程序启动后就会立即加载到内存.
缺点:启动比较慢.
代码如下:

#include <iostream>
using namespace std;

template<class T>
class Singleton
{
public:
    static T* GetSingleton()
    {
        return &value;
    }
private:
    static T value;
};
template<class T>
T Singleton<T>::value = T();

int main()
{
    Singleton<int>::GetSingleton();
    return 0;
}

懒汉模式

含义:启动的时候不加载,只有当使用的时候才会加载到内存.

#include <iostream>
using namespace std;

//懒汉模式
template<class T>   //类模板
class singleton
{
public:
    static T* GetSingleton()
    {
        if(value == NULL)
        {
            value = new T();
        }
        return value;
    }
private:
    static T* value;
};
template<class T>
T* singleton<T>::value = NULL;

int main()
{
    singleton<int>::GetSingleton();
    return 0;
}

上面这个代码存在一个很重要的问题:

1.如果在多线程的环境下,在函数GetSingleton()中如果进行判断时如果同时多个线程频繁的进行判断,那么就会存在线程安全问题,如果多个线程都判断为空那么就会new出来很多对象,那么明显就是不安全的.
解决:加锁,在判断前进行加锁,在出了if判断再进行解锁.
问题:如果有多个进程频繁的获取锁,然后再进行判断,然后再释放.那么效率就会下降,加锁和解锁也是一种消耗.
解决:在加锁前再进行一次判断,如果为空才进行进行加锁.这样就会大大减少了加解锁的消耗.

具体的代码如下:
template<class T>
class singleton
{
public:
    static T* GetSingleton()
    {
        if(value == NULL)    //这样就只有为空才会进来进行加锁解锁(这样就不会频繁获取锁)
        {
            lock(); //这是一句伪代码(加锁)
            //如果在这儿加锁,所有的线程到这儿都会先加锁(这也是一种消耗),再判断,这样就会造成效率低.所以在这儿之前再进行一次判断
            //但是在这儿加锁也会满足线程安全
            if(value == NULL)
            {
                value = new T();
            }
            unlock();  //伪代码(解锁)
        }
        return value;
    }
private:
    static volatile  T* value;  //加上volatile为了防止编译器过度优化
};
template<class T>
volatile T* singleton<T>::value = NULL;
<think>好的,我现在需要帮助用户找到关于C++中使用单例模式实现TCP通信的示例代码。用户提到他们已经有了一些引用内容,包括单例模式的智能指针实现和网络编程相关的部分。我需要结合这些信息,生成一个符合用户需求的示例代码。 首先,我需要回忆单例模式的基本结构。单例模式确保一个类只有一个实例,并提供全局访问点。通常在C++中,这通过私有构造函数、静态实例成员和静态获取实例的方法来实现。用户提供的引用[1]中使用了双重检查锁定和智能指针,这可能有助于线程安全。 接下来是关于TCP通信的部分。引用[2]提到了绑定套接字和使用TCP/IPv4协议栈,所以需要包含创建socket、绑定、监听、接受连接等步骤。我需要将这些步骤整合到单例类中,确保单例类管理TCP连接的相关操作。 然后,我需要考虑线程安全。用户提供的示例中使用了互斥锁,所以在获取实例时应该使用双重检查锁定来减少锁的开销。同时,使用智能指针(如shared_ptr)来管理实例,避免内存泄漏。 现在开始构建代码结构。单例类应该包含socket的文件描述符、地址结构等成员变量。静态方法instance()负责返回单例实例,并在首次创建时初始化TCP连接。构造函数私有化,防止外部实例化。 在初始化过程中,需要创建socket,设置地址结构(如使用INADDR_ANY和指定端口),绑定socket,并开始监听。可能还需要处理错误情况,比如socket创建失败或绑定失败,这时可以抛出异常或记录错误。 此外,考虑到示例的完整性,可能需要添加连接接受的方法,比如accept_connection(),该方法调用accept函数并返回客户端的信息。析构函数需要关闭socket以确保资源释放。 测试代码部分,用户可能希望看到如何获取单例实例并使用其方法。例如,调用accept_connection()并输出客户端IP和端口。 需要注意的点:确保代码中的错误处理,比如检查socket操作返回值;使用适当的命名空间和头文件;正确实现双重检查锁定以避免多线程问题;智能指针的使用是否正确,避免循环引用或内存泄漏。 最后,根据用户的要求生成相关问题,这些问题应该围绕单例模式在TCP中的应用、线程安全、资源管理等方面展开,帮助用户进一步理解和应用示例中的概念。</think>以下是一个基于C++单例模式实现TCP通信的示例代码,结合了双重检查锁定和智能指针技术,支持IPv4协议栈: ```cpp #include <memory> #include <mutex> #include <sys/socket.h> #include <netinet/in.h> class TCPSingleton { public: static std::shared_ptr<TCPSingleton> instance() { if (!s_instance) { std::lock_guard<std::mutex> lock(s_mutex); if (!s_instance) { s_instance = std::shared_ptr<TCPSingleton>(new TCPSingleton()); s_instance->init_socket(); } } return s_instance; } void accept_connection() { sockaddr_in client_addr{}; socklen_t client_len = sizeof(client_addr); int client_fd = accept(_socket_fd, (sockaddr*)&client_addr, &client_len); // 处理客户端连接... } private: TCPSingleton() = default; ~TCPSingleton() { close(_socket_fd); } void init_socket() { _socket_fd = socket(AF_INET, SOCK_STREAM, 0); if (_socket_fd < 0) throw std::runtime_error("Socket creation failed"); sockaddr_in address{}; address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(8080); if (bind(_socket_fd, (sockaddr*)&address, sizeof(address)) < 0) { close(_socket_fd); throw std::runtime_error("Bind failed"); } listen(_socket_fd, 5); } static std::shared_ptr<TCPSingleton> s_instance; static std::mutex s_mutex; int _socket_fd = -1; }; std::shared_ptr<TCPSingleton> TCPSingleton::s_instance = nullptr; std::mutex TCPSingleton::s_mutex; // 使用示例 auto tcp = TCPSingleton::instance(); tcp->accept_connection(); ``` 代码特点说明: 1. 使用双重检查锁定模式确保线程安全[^1] 2. 采用智能指针管理实例生命周期 3. 封装socket创建、绑定、监听等TCP通信基础操作[^2] 4. 默认使用IPv4协议栈和8080端口 5. 异常处理机制保障初始化可靠性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值