剑指offer系列--------01.单例模式

单例模式:只有一个类实例化对象

   1. 私有构造

   2.定义该类型的唯一对象

   3. 使用静态方法返回一个对象

饿汉单例模式

//无论用不用到该对象,都会在使用之前就直接创建唯一对象

//在类开始被加载后,就会创建对象,因此它是一个线程安全的

class Singleton
{
public:
    static Singleton *getInstance()
    {
        return instance;
    }
private:
    Singleton() { cout << "Singleton()" << endl; }
    Singleton(const Singleton &instance) { cout << "Singleton(const Singleton &)" << endl; }
    static Singleton *instance;
};
Singleton* Singleton::instance = new Singleton();


int main()
{
    Singleton *p1 = Singleton::getInstance();
    Singleton *p2 = Singleton::getInstance();
    Singleton *p3 = Singleton::getInstance();

    cout << p1 << " " << p2 << " " << p3 << endl;
    return 0;
}

非线程安全的懒汉单例模式

class Singleton
{
public:
    static Singleton *getInstance()
    {
        if (instance == nullptr)
        {
            instance = new Singleton();
        }
        return instance;
    }

private:
    static Singleton *instance;
    Singleton() { cout << "Singleton()" << endl; }
    Singleton(const Singleton &instance) { cout << "Singleton(const Singleton &)" << endl; }
    ~Singleton() { cout << "~Singleton()" << endl; }

    class Release
    {
    public:
        ~Release()
        {
            if (instance != nullptr)
            {
                delete instance;
                instance = nullptr;
            }
        }
    };
    static Release del;
};
Singleton *Singleton::instance = nullptr;
Singleton::Release Singleton::del;

int main()
{
    Singleton *p1 = Singleton::getInstance();
    Singleton *p2 = Singleton::getInstance();
    cout << p1 << " " << p2 << endl;
    return 0;
}


 

线程安全的单例模式

//频繁的加锁解锁 效率低下

class Singleton
{
public:
    static Singleton *getInstance()
    {
        pthread_mutex_lock(&_mutex);
        if (instance == nullptr)
        {
            instance = new Singleton();
        }
        pthread_mutex_unlock(&_mutex);
        return instance;
    }

private:
    Singleton()
    {
        cout << "Singleton()" << endl;
    }
    Singleton(const Singleton &instance)
    {
        cout << "Singleton(const Singleton&)" << endl;
    }
    ~Singleton()
    {
        pthread_mutex_destroy(&_mutex);
        cout << "~Singleton()" << endl;
    }

    class Release
    {
    public:
        ~Release()
        {
            if (instance != nullptr)
            {
                delete instance;
                instance = nullptr;
            }
        }
    };
    static Release rel;

    static Singleton *instance;
    static pthread_mutex_t _mutex;
};
Singleton *Singleton::instance = nullptr;
pthread_mutex_t Singleton::_mutex = PTHREAD_MUTEX_INITIALIZER;

Singleton::Release Singleton::rel;

int main()
{
    Singleton *p1 = Singleton::getInstance();
    Singleton *p2 = Singleton::getInstance();
    cout << p1 << " " << p2 << endl;
    return 0;
}


 

线程安全的单例模式

//锁+双重判断  减少加锁解锁

class Singleton
{
public:
    static Singleton *getInstance()
    {
        if (instance == nullptr)
        {
            pthread_mutex_lock(&_mutex);
            /*
            问题:在外面已经进行一次instance判空 为什么加锁后还要进行判空
            此时需要在进行一次判空
            原因:有多个线程在第一次判断空时进入了第一个if语句
            此时如果不在进行判空 在解锁后会有线程再次去进行new对象
            */
            if (instance == nullptr)
            {
                instance = new Singleton();
            }
            pthread_mutex_unlock(&_mutex);
        }

        return instance;
    }

private:
    Singleton()
    {
        cout << "Singleton()" << endl;
    }
    Singleton(const Singleton &instance)
    {
        cout << "Singleton(const Singleton&)" << endl;
    }
    ~Singleton()
    {
        pthread_mutex_destroy(&_mutex);
        cout << "~Singleton()" << endl;
    }

    class Release
    {
    public:
        ~Release()
        {
            if (instance != nullptr)
            {
                delete instance;
                instance = nullptr;
            }
        }
    };
    static Release rel;

    static Singleton *instance;
    static pthread_mutex_t _mutex;
};
Singleton *Singleton::instance = nullptr;
pthread_mutex_t Singleton::_mutex = PTHREAD_MUTEX_INITIALIZER;

Singleton::Release Singleton::rel;

int main()
{
    Singleton *p1 = Singleton::getInstance();
    Singleton *p2 = Singleton::getInstance();
    cout << p1 << " " << p2 << endl;
    return 0;
}

划重点!!!

单例模式的类模板

无论类型怎么变,都可以用这个类模板

/************************************************************************
 singleton模式类模板
 1:延迟创建类实例    2:double check    3:互斥访问    4:模板
 ************************************************************************/
 
 template<class T>
 class CSingleton
 {
 private:
     static T* _instance;
     CSingleton(void);
     static CThreadLockCs lcs;
 public:
     static T* Instance(void);
     static void Close(void);
 };
 
 //模板类static变量
 template<class T> 
 T*  CSingleton<T>::_instance = NULL;
 
 
 //模板类方法实现
 template<class T>
 CSingleton<T>::CSingleton(void)
 {    
 }
 
 template<class T>
 T*  CSingleton<T>::Instance(void)
 {
     //double-check
     //延迟创建,只有调用方访问Instance才会创建类实例
     if (_instance == NULL)
     {
         //互斥访问锁,用CriticalSection实现
         lcs.lock();
         if (_instance == NULL)
         {
             _instance = new T;
         }
         lcs.unlock();
     }
     return _instance;
 }
 
 template<class T>
 void CSingleton<T>::Close(void)
 {
     if (_instance)
     {
         delete _instance;
     }
 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据引用\[1\],题目是要求翻转一个英文句子中单词的顺序,但保持单词内字符的顺序不变。例如,输入字符串"I am a student.",则输出"student. a am I"。 根据引用\[2\]和引用\[3\],提供了三种解法。解法1是通过字符串遍历的方式,将每个字符按照翻转后的位置重新拼接成一个新的字符串。解法2是通过字符串切分与拼接的方式,先将前n个字符切分出来,然后将剩余的字符与切分出来的字符进行拼接。解法3是通过三次翻转的方式,先翻转前n个字符,再翻转剩余的字符,最后再整体翻转整个字符串。 根据题目的要求,你可以选择其中一种解法来实现。 #### 引用[.reference_title] - *1* [Offer58-Ⅰ—翻转单词顺序](https://blog.csdn.net/qq_39172845/article/details/124604122)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Offer58-Ⅱ—左旋转字符串](https://blog.csdn.net/qq_39172845/article/details/124625810)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值