1. 程式人生 > >effective c++條款14

effective c++條款14

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(); }

同步順利時,顯示的都是正常的值,不順利時,顯示的是未初始化的值