-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathRAII.cpp
111 lines (100 loc) · 3 KB
/
RAII.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include <iostream>
//#define RAII //whether to use RAII mode
/*
this is a demo of RAII class
*/
//https://stackoverflow.com/questions/2321511/what-is-meant-by-resource-acquisition-is-initialization-raii
//https://zhuanlan.zhihu.com/p/34660259
//https://stackoverflow.com/questions/2709719/throwing-out-of-range-exception-in-c/2709733
//https://www.gergel.im/2016/06/05/dtors-not-always-called-when-exceptions-are-thrown/
//http://www.cplusplus.com/doc/tutorial/dynamic/
//https://stackoverflow.com/questions/19594851/pointer-being-freed-was-not-allocateddelete-one-element-in-an-array
#ifdef RAII
class ResourceManager{
public:
ResourceManager(): size(0), resource(nullptr){
std::cout << "resource initialized" << std::endl;
}
ResourceManager(int size): size(size){
resource = new int[size];
std::cout << "resource initialized" << std::endl;
}
~ResourceManager(){
//notice it's not "delete resource"!
delete [] resource;
std::cout << "resource released" << std::endl;
}
void set(int index, int value){
if(index < 0 || index > size){
throw std::out_of_range("invalid index!");
}
resource[index] = value;
}
int get(int index){
if(index < 0 || index > size){
throw std::out_of_range("invalid index!");
}
return resource[index];
}
private:
int* resource;
int size;
};
#else
void set(int* resource, int size, int index, int value){
if(index < 0 || index > size){
throw std::out_of_range("invalid index!");
}
resource[index] = value;
}
int get(int* resource, int size, int index){
if(index < 0 || index > size){
throw std::out_of_range("invalid index!");
}
return resource[index];
}
#endif
int main(){
try{
#ifdef RAII
ResourceManager rm(100);
std::cout << "set 100th element..." << std::endl;
rm.set(100, 0);
std::cout << "set 101th element..." << std::endl;
rm.set(101, 0);
//destructor will be called even if there is an exception
#else
int* resource;
int size = 100;
resource = new int[size];
std::cout << "resource initialized" << std::endl;
std::cout << "set 100th element..." << std::endl;
set(resource, size, 100, 0);
std::cout << "set 101th element..." << std::endl;
set(resource, size, 101, 0);
//notice it's not "delete resource"!
delete [] resource; //this will not be executed
std::cout << "resource released" << std::endl;
#endif
}catch(...){
throw;
}
return 0;
}
//result of RAII mode
/*
resource initialized
set 100th element...
set 101th element...
resource released
libc++abi.dylib: terminating with uncaught exception of type std::out_of_range: invalid index!
Abort trap: 6
*/
//result of not RAII mode
/*
resource initialized
set 100th element...
set 101th element...
libc++abi.dylib: terminating with uncaught exception of type std::out_of_range: invalid index!
Abort trap: 6
*/