effective c++條款14
阿新 • • 發佈:2019-01-24
1.複製RAII物件必須一併複製它所管理的資源,所以資源的copying行為決定RAII物件的copying行為
2.普遍而常見的的RAII class copying行為是:抑制copying,施行引用計數法
第1條的意思是:我們要根據資源的copying行為去選擇所用的管理類,
比如,
我之前有個類
class Lock
{
public:
explicit Lock(mutex* pm):mutexPtr(pm){mutexPtr->lock();}
~Lock() {mutexPtr->unlock();}
private:
mutex* mutexPtr;
}
這個類其實就是實現互斥量的鎖定和解鎖,但是如果要copy呢
1.禁止複製,這對互斥量來說其實還是很合理的
2.採用引用計數,引用計數就是複製時並不增加資源的數量,增加計數,當計數為0時,釋放資源
我們這裡考慮mutex的copying行為,決定採用shared_ptr巢狀Lock類,定義新的管理類,順便說下,shared_ptr可以自定義自己的刪除器
這是修改後的程式碼
void unlock(mutex* pm);
class Lock
{
public:
explicit Lock(mutex* pm) :MutexPtr(pm, unlock){ MutexPtr.get ()->lock(); }//這裡我們把unlock定義為刪除器,所以就不需要析構函數了
private:
shared_ptr<mutex> MutexPtr;
};
void unlock(mutex* pm)
{
pm->unlock();
}
再找個例子
#include<windows.h>
#include <iostream>
#include <memory>
#include <string>
#include<process.h>
#include<stdlib.h>
#include<vector>
#include <mutex>
using namespace std;
vector<int> g_vec;
HANDLE g_read, g_write;
//HANDLE hMutex;
mutex mx;
unsigned int WINAPI WorkThreadRead(void* param);
unsigned int WINAPI WorkThreadWrite(void* param);
void unlock(mutex* pm);
class Lock
{
public:
explicit Lock(mutex* pm) :MutexPtr(pm, unlock){ MutexPtr.get()->lock(); }
private:
shared_ptr<mutex> MutexPtr;
};
int main()
{
//hMutex = CreateMutex(NULL, true, NULL);
g_read = (HANDLE)_beginthreadex(NULL, 0, WorkThreadRead, NULL, 0, NULL);
g_write = (HANDLE)_beginthreadex(NULL, 0, WorkThreadWrite, NULL, 0, NULL);
CloseHandle(g_read);
CloseHandle(g_write);
system("pause");
return 0;
}
unsigned int WINAPI WorkThreadRead(void* param)
{
while (true)
{
Lock a(&mx);
//WaitForSingleObject(hMutex, INFINITE);
for (vector<int>::iterator it = g_vec.begin(); it != g_vec.end(); ++it)
{
cout << (*it) << endl;
}
//ReleaseMutex(hMutex);
}
}
unsigned int WINAPI WorkThreadWrite(void* param)
{
srand(GetTickCount());
while (true)
{
Lock a(&mx);
//WaitForSingleObject(hMutex, INFINITE);
if (g_vec.size() > 0)
{
if (rand() % 100 > 50)
{
g_vec.push_back(rand() % 10000);
}
else
{
g_vec.erase(g_vec.begin());
}
}
else
{
g_vec.push_back(rand() % 10000);
}
//ReleaseMutex(hMutex);
Sleep(10);
}
}
void unlock(mutex* pm)
{
pm->unlock();
}
同步順利時,顯示的都是正常的值,不順利時,顯示的是未初始化的值