1 设计模式
设计模式:代码的一些写法(跟常规写法不一样),程序灵活,维护起来可能方便,但别人接管或者阅读就会很难受。
用设计模式理念写出来的代码比较晦涩;应付大型项目时,把项目的开发经验、模块划分经验,总结整理而成。
建议:设计模式有着独特的优势,但要活学活用,不要深陷其中,生搬硬套。
2 单例设计模式
单例设计模式使用频率较高
单例:整个项目中,有某个或者某些特殊的类,属于该类的对象,只能创建一个。
#include <vector>
#include <thread>
#include <mutex>
using namespace std;
class Myclass //单例类
{
private:
Myclass(){} //私有化了构造函数,只能他自己构造自己
private:
static MyCAS *m_instance; // 静态成员变量
public:
static MyCAS *GetIstance()
{
// 双重查锁,解决多个线程争夺锁问题。
//if(m_instance == NULL)
//{
std::lock_guard<std::mutex> mymutex(Gmutex);//因为不能两个线程同时构造
if(m_instance == NULL)
{
m_instance = new Myclass();
//static helpRelease c1; //类内的静态数据成员,它始终驻留在全局数据区,直到程序运行结束。
}
//}
}
// 类中套类,解决析构问题
//class helpRelease
//{
//public:
// helpRelease(){}
// ~helpRelease()
// {
// if(MyCAS::m_instance)
// {
// delete Myclass::m_instance;
// Myclass::minstance = NULL;
// }
// }
//};
};
// 线程入口函数
void mythread()
{
cout << "线程开始:" << endl;
MyCAS *p_a = MyCAS::GetIstance();
cout << "线程结束:" << endl;
return;
}
// 类静态变量初始化为空
MyCAS *MyCAS::m_instance = NULL;
int main()
{
//Myclass *p_w = Myclass::GetInstance();//得到一个单例对象
//MyCAS *p_b = MyCAS::GetIstance();// 还是原对象(可以查看其地址验证)
std::thread mytobj1(mythread);
std::thread mytobj2(mythread);
mytobj1.join();
mytobj2.join();
return0;
}
如果没有注释代码,以上程序是存在风险的:
①new 生成的对象没有手动析构。—类中套类解决析构问题。
②每创建单例对象时多个线程都要争夺锁。----双重查锁,解决多线程重复拿锁的问题。
3 std::call_once() C++11引入的函数,该函数的第二个参数是一个函数名a()
功能:能够保证a()只调用一次。具备互斥量的能力,而且效率比互斥量更高。
需要和一个标记结合使用,这个标记 std::once_flag;其实once_flag是一个结构
通过此标记来决定函数a()是否执行,调用后就将此标记设置为已调用状态。
示例:
#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
using namespace std;
std::mutex Gmutex;
std::once_flag g_flag;//这是个系统定义的标记
class MyCAS //单例类
{
static void CreatInstance()//只调用一次的函数
{
std::chrono::microseconds dura(10000);
std::this_thread::sleep_for(dura);
m_instance = new MyCAS();// 想办法在程序结束后释放,怎么弄呢?
static Releaseclass c1; // 类内的静态数据成员,它始终驻留在全局数据区,直到程序运行结束。
}
private:
MyCAS() {};//私有化了构造函数
private:
static MyCAS *m_instance; // 静态成员变量
public:
static MyCAS *GetIstance()
{
std::call_once(g_flag, CreatInstance);//几个线程一起来到这,只要有一个执行了,这个函数标记就说明不再执行了
return m_instance;
}
//类中套类,实现释放对象
class Releaseclass
{
public:
Releaseclass(){}
~Releaseclass()
{
if (MyCAS::m_instance)
{
delete MyCAS::m_instance;
MyCAS::m_instance = NULL;
}
}
};
};
// 线程入口函数
void mythread()
{
cout << "线程开始:" << endl;
MyCAS *p_a = MyCAS::GetIstance();
cout << "线程结束:" << endl;
return;
}
// 类静态变量初始化
MyCAS *MyCAS::m_instance = NULL;
int main()
{
std::thread mytobj1(mythread);
std::thread mytobj2(mythread);
mytobj1.join();
mytobj2.join();
return 0;
}