http://qtandopencv.blogspot.com/2013/10/why-raii-is-must-know-technique-for-c.htmlRAII is a must know technique for c++ programmers, no excuse.
翻墙不便;拷贝在此,方便查看。
//z 2013-11-13 17:32:19 IS2120@BG57IV3 T3051779025.K.F2671830637[T47,L513,R21,V537]
RAII
(
resource
acquisition is initialization), in a nutshell, is same as "
let the object handle the resource
".I use the word
resource
but
not memory
, because
RAII
can guard
more than memory
(mutex, db connnection, socket, file and every resource you can think of).There are many
blogs
,
famous technical forum
,
gurus suggestion
, mention and emphasize how important and what
RAII
is.
C++ is a big, complexity language, I have no idea I need to take how many years to learn every corners of this powerful beast, but we
do not need to
learn all of it. We only need to know the most essential part of c++,
RAII
is one of them.You may not use any
TMP
(
template meta programming
) ,
multi inheritance
(please think carefully before you use this feature), design any
allocators
, don't know what is
policy based design
, have no idea how
type_traits
work, do not familiar with
operator overloading
, but you will always find out that
RAII
could help you write good codes, make your codes become much more easier to
maintain
,
read
and more
robust
.
If you don't believe it, let us look at a simple example.
#include <iostream>
#include <new>
int main()
{
int *arr = nullptr;
int *max = nullptr;
double *double_arr = nullptr;
try{
arr = new int[100];
max = new int(300);
double_arr = new double[300];
//.....do something......
//handle your garbages if something happen
goto cleanUp;
//......
}catch(std::bad_alloc const &ex){
std::cerr<<ex.what()<<std::endl;
}
cleanUp:
if(arr){
delete []arr;
arr = nullptr;
}
if(max){
delete max;
max = nullptr;
}
if(double_arr){
delete []double_arr;
double_arr = nullptr;
}
}
What is the problem with this example?They are perfectly legal and safe in C++?If you don't get it, let me ask you a problem.
Q : What if we need to handle more resource?
Naive answer(bad practice) : add more if else
The suck codes proposed by the naive answer may look like
#include <iostream>
#include <new>
int main()
{
int *arr = nullptr;
int *max = nullptr;
double *double_arr = nullptr;
float *float_max = nullptr;
float *float_arr = nullptr;
try{
arr = new int[100];
max = new int(300);
double_arr = new double[300];
float_max = new float(3.14);
float_arr = new float[300];
//.....do something......
//handle your garbages if something happen
goto cleanUp;
//......
}catch(std::bad_alloc const &ex){
std::cerr<<ex.what()<<std::endl;
}
cleanUp:
if(arr){
delete []arr;
arr = nullptr;
}
if(max){
delete max;
max = nullptr;
}
if(double_arr){
delete []double_arr;
double_arr = nullptr;
}
if(float_max){
delete float_max;
float_max = nullptr;
}
if(float_arr){
delete []float_arr;
float_arr = nullptr;
}
}
You will have to alter
two places whenever you need to add or delete the resources.This kind of c style codes are error prone , hard to maintain and unbearable , they are almost as worse as (even worse than it if we have to take care of exception) the old school c codes which heavily depends on goto to clean up resources, this kind of codes will become unreadable in short times. I believe this is one of the reason why Bjarne
said " Aim to write idiomatic C++: avoid simply writing code in the style of your previous language using C++ syntax; there is little to be gained from simply changing syntax.
".For any C++ programmers who know how important and powerful
RAII
is, they can't bear this kind of horrible codes.
How could
RAII
help us?
#include <iostream>
#include <memory>
#include <new>
#include <vector>
int main()
{
try{
std::vector<int> arr(100);
std::unique_ptr<int> max(new int(300));
std::vector<double> double_arr(300);
std::unique_ptr<double> double_max(new double(300));
std::vector<float> float_arr(100);
std::unique_ptr<float> float_max(new float(100));
//...do something....
//the object will release the resources automatically
//even the exceptions thrown
}catch(std::bad_alloc const &ex){
std::cerr<<ex.what()<<std::endl;
}
}
Do you see that?The codes become
much more easier to read
, because we don't need to release the resource manually, we don't need to change the codes in two places.The codes become more
robust
, because we
will not forget
to release the resources again.More than that, it is
exception safe
too.
There are many kinds of coding standards, rules in many teams, not all coding standards suit for all teams and all applications.Whatever it is,
RAII
is a
must know technique
and should be obey when you can. If you are using
delete
in your codes, maybe you are doing something
wrong
or writing
worse codes
in C++, even you need to use delete(building some infrastructures, like smart pointer, containers and so on), do remember to
protect it by object,
always remember
to follow the rule of
RAII
.Pointer is
good at
access data
, but
not resource management
, leave your resource to class(
RAII
).
In my humble opinion, if a C++ programmer don't know the concepts of
RAII
, he/she will generate
lower quality, worse performance, less reliable codes
most of the times(just like the suck codes show by the examples). It is always a good question to test your interviewers, ask them they notice how important
RAII
in C++ or not.If they don't know it, don't hire them(or teach them if you think the candidates are worth to).If you were an interviewer and find out the company don't take
RAII
seriously, then I bet the codes of this company must be
extremely messy, buggy, hard to maintain and stinking
. The more you realize about how important
RAII
is, the more you can't stand with those
alien artifacts
.
//z 2013-11-13 17:32:19 IS2120@BG57IV3 T3051779025.K.F2671830637[T47,L513,R21,V537]