C++中的RAII全称是“Resource acquisition is initialization”,直译为“资源获取时就初始化”
一般情况下,RAII临时对象不允许复制和赋值,当然更不允许在heap上创建,因为如果允许了复制和赋值,有些时候作为形参传入该对象时候,采用了默认构造函数,无法对某些变量或操作初始化,导致析构的时候,发生问题,例如:
1.线程锁的情况:(下例)由于进出临界区加锁解锁是成对使用EnterCriticalSection()和LeaveCriticalSection(),如果使用参数传值,就发生参数的复制,调用复制构造函数(操作符类似),然而并没有调用到EnterCriticalSection(),最终就没有起到加锁的作用。
class MyLock
{
public:
MyLock()
{
EnterCriticalSection(&cs);
}
~MyLock()
{
LeaveCriticalSection(&cs);
}
MyLock( const MyLock &);
MyLock operator =(const MyLock &);
};
void process(MyLock lock)
{
}
unsigned int ThreadFun(PVOID pv)
{
MyLock lock;
int *para = (int *) pv;
process(lock);
for (int i = 0; i < 10; ++i)
{
++gGlobal;
cout<< "Thread " <<*para<<endl;
cout<<gGlobal<<endl;
}
return 0;
}
如果将process(MyLock lock)改为process(MyLock &lock),或者将类MyLock的复制构造函数和操作符重载设置为私有,可以解决问题;
private:
MyLock( const MyLock &);
MyLock operator =(const MyLock &);
2、内存处理不当导致泄露
- class RAII{
- public:
- RAII(Resource* aResource):r_(aResource){}
- ~RAII() {delete r_;}
- Resource* get() {return r_ ;}
- private:
- Resource* r_;
- };