一、单例设计模式
class Test
{
public:
static Test *GetInstance()
{
if (nullptr == ptrTest)
{
ptrTest = new Test();
static Delete cl; //定义一个静态释放对对象
}
return ptrTest;
}
class Delete //类中嵌套来释放对象
{
public:
~Delete()
{
if (Test::ptrTest)
{
delete Test::ptrTest;
Test::ptrTest = nullptr;
}
}
};
void func()
{
cout << "测试类" << endl;
}
private:
Test() {};
~Test()
{
};
private:
static Test *ptrTest;
};
Test *Test::ptrTest = nullptr;
int main()
{
Test::GetInstance()->func();
cout << "I Love China" << endl;
return 0;
}
二、单例设计模式共享数据分析
- 问题分析:需要我们自己创建线程(而不是主线程)中来创建 Test 这个单例类的对象,这种线程可能不止两个(最少两个),我们可能会面临GetInstance()这种成员函数需要互斥
//线程入口函数 void MyThread() { cout << "我的线程开始了" << endl; Test *ptrTest = Test::GetInstance(); //这里可能就有问题 } int main() { thread obj1(MyThread); thread obj2(MyThread); obj1.join(); obj2.join(); cout << "I Love China" << endl; return 0; }
- 解决办法:加双重锁定
if (nullptr == ptrTest) //双重锁定(双重检查)
{
unique_lock<mutex> unique(mutex1);
if (nullptr == ptrTest)
{
ptrTest = new Test();
static Delete cl;
}
}
完整代码演示:
std::mutex mutex1;
class Test
{
public:
static Test *GetInstance()
{
if (nullptr == ptrTest) //双重锁定(双重检查)
{
unique_lock<mutex> unique(mutex1);
if (nullptr == ptrTest)
{
ptrTest = new Test();
static Delete cl;
}
}
return ptrTest;
}
class Delete //类中嵌套来释放对象
{
public:
~Delete()
{
if (Test::ptrTest)
{
delete Test::ptrTest;
Test::ptrTest = nullptr;
}
}
};
void func()
{
cout << "测试类" << endl;
}
private:
Test() {};
~Test()
{
};
private:
static Test *ptrTest;
};
Test *Test::ptrTest = nullptr;
//线程入口函数
void MyThread()
{
cout << "我的线程开始了" << endl;
Test *ptrTest = Test::GetInstance(); //这里可能就有问题
}
int main()
{
thread obj1(MyThread);
thread obj2(MyThread);
obj1.join();
obj2.join();
cout << "I Love China" << endl;
return 0;
}
三、std::call_once() :能够保证函数A()只被调用一次
- C++11 引入的函数,该函数的第二个参数是一个函数名,具备互斥量这种能力,效率上更高
- call_once() 需要与一个标记结合使用,这个标记 std::once_flag; 其实 once_flag 是一个结构,决定对应的函数A() 是否被执行,调用 call_once()成功后,就把这个标记设置为一种已调用状态,后续再次调用 call_once(), 只要once_flag 被设置为了 “已调用”状态,那么对应的函数A()就不会被执行了
重要代码部分:
static void CreateInstance()
{
ptrTest = new Test();
static Delete cl;
}
static Test *GetInstance()
{
std::call_once(g_flag, CreateInstance); //两个线程同时执行到这里
return ptrTest;
}
完整代码:
std::once_flag g_flag; //定义一个系统的标记
class Test
{
public:
static void CreateInstance()
{
ptrTest = new Test();
static Delete cl;
}
static Test *GetInstance()
{
std::call_once(g_flag, CreateInstance); //两个线程同时执行到这里
return ptrTest;
}
class Delete //类中嵌套来释放对象
{
public:
~Delete()
{
if (Test::ptrTest)
{
delete Test::ptrTest;
Test::ptrTest = nullptr;
}
}
};
void func()
{
cout << "测试类" << endl;
}
private:
Test() {};
~Test()
{
};
private:
static Test *ptrTest;
};
Test *Test::ptrTest = nullptr;
//线程入口函数
void MyThread()
{
cout << "我的线程开始了" << endl;
Test *ptrTest = Test::GetInstance(); //这里可能就有问题
}
int main()
{
thread obj1(MyThread);
thread obj2(MyThread);
obj1.join();
obj2.join();
cout << "I Love China" << endl;
return 0;
}