一个典型的体现RAII的例子
RAII是什么?
RAII是Resource Acquisition Is Initialization(wiki上面翻译成 “资源获取就是初始化”)的简称,是C++语言的一种管理资源、避免泄漏的惯用法。利用的就是C++构造的对象最终会被销毁的原则。RAII的做法是使用一个对象,在其构造时获取对应的资源,在对象生命期内控制对资源的访问,使之始终保持有效,最后在对象析构的时候,释放构造时获取的资源
来看cppreference的解释RAII
提供的示例中,lock_guard类型的lk作为栈对象,当离开作用域时销毁,自动将互斥锁m解锁。
std::mutex m;
void bad()
{
m.lock(); // acquire the mutex
f(); // if f() throws an exception, the mutex is never released
if(!everything_ok()) return; // early return, the mutex is never released
m.unlock(); // if bad() reaches this statement, the mutex is released
}
void good()
{
std::lock_guard<std::mutex> lk(m); // RAII class: mutex acquisition is initialization
f(); // if f() throws an exception, the mutex is released
if(!everything_ok()) return; // early return, the mutex is released
} // if good() returns normally, the mutex is released
以下例子在线程结束时自动析构线程对象,释放资源
Thead虚基类:
#include <pthread.h>
class Thread
{
public:
Thread();
virtual ~Thread();
void Start();
void Join();
void SetAutoDelete(bool autoDelete);
private:
static void* ThreadRoutine(void* arg);
virtual void Run() = 0;
pthread_t threadId_;
bool autoDelete_;
};
Thread::Thread() : autoDelete_(false)
{
cout<<"Thread ..."<<endl;
}
Thread::~Thread()
{
cout<<"~Thread ..."<<endl;
}
void Thread::Start()
{
pthread_create(&threadId_, NULL, ThreadRoutine, this); //创建线程
}
void Thread::Join()
{
pthread_join(threadId_, NULL);
}
void* Thread::ThreadRoutine(void* arg)
{
Thread* thread = static_cast<Thread*>(arg); //基类指针指向子类对象
thread->Run(); //执行子类虚函数
if (thread->autoDelete_) //当线程执行完任务后,自行释放该对象资源
delete thread;
return NULL;
}
void Thread::SetAutoDelete(bool autoDelete)
{
autoDelete_ = autoDelete;
}
继承虚基类,实现虚函数Run
class TestThread : public Thread
{
public:
TestThread(int count) : count_(count)
{
cout<<"TestThread ..."<<endl;
}
~TestThread()
{
cout<<"~TestThread ..."<<endl;
}
private:
void Run()
{
while (count_--)
{
cout<<"this is a test ..."<<endl;
sleep(1);
}
}
int count_;
};
main函数测试
TestThread* t2 = new TestThread(5);
t2->SetAutoDelete(true); //设置自动销毁对象
t2->Start();
t2->Join();