-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRAII.cpp
More file actions
107 lines (93 loc) · 2.71 KB
/
Copy pathRAII.cpp
File metadata and controls
107 lines (93 loc) · 2.71 KB
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
#include <iostream>
#include <memory>
#include <mutex>
#include <thread>
// Mutex
struct BufferClass
{
void display() {};
};
struct SomeDataSource
{
bool readIntobuffer(BufferClass& buffer)
{
return true;
};
};
bool fn(std::mutex &someMutex, SomeDataSource &src)
{
std::lock_guard lock{someMutex}; // std::unique_lock can make more choices(Need to lock/unlock by hand)
try
{
BufferClass buffer;
if (not src.readIntobuffer(buffer))
{
return false;
}
buffer.display();
}
catch (...)
{
throw;
}
return true;
}
// Thread
struct SomeClass
{
void fnn();
};
void SomeClass::fnn()
{
auto worker{std::jthread{[](){ /* do something*/ }}};
}
void doss(){};
auto worker{std::jthread{doss}}; // Pass the function name (not the call) or a lambda anonymous function.
// File
struct file_closer{ // The parentheses operator () is overloaded; this is called a "functor".
void operator()(FILE* stream) const{fclose(stream);}
};
using cfile = std::unique_ptr<FILE, file_closer>; // The second parameter can be a structure (functor) or a function pointer; the default is to delete the pointer.
// C++20
using pcfile = std::unique_ptr<FILE, decltype([](FILE* fp){fclose(fp);})>;
auto make_cfile(char const* filename, char const* mode){
FILE* stream{fopen(filename, mode)};
if(not stream){
throw std::runtime_error("Failed to open file");
}
return cfile{stream};
}
void fn(){
auto file{make_cfile("filename.txt", "w")};
fprintf(file.get(), "Data for the file.");
}
// RAII class usage
template <class Mutex> // Compatible with various types of mutexes
class unique_unlock{
public:
explicit unique_unlock(std::unique_lock<Mutex> &p_lock)
: lock(p_lock){lock.unlock();} // Member initialization, lock is a reference to p_lock. The same as self.name = name.
~unique_unlock(){lock.lock();} // When it leaves its scope and is destroyed, it automatically calls lock().
private:
std::unique_lock<Mutex> &lock;
};
std::mutex mut;
void fm(){
std::unique_lock ul{mut}; // ul takes control of mut, others cannot operate mut
// Do some work protected by the mutex
{
unique_unlock u{ul};
// Do some work not protected
}
// The resource was deleted and the work protected by the mutex again
}
int main()
{
// pointers
auto ptr1{std::make_unique<float>(10.0f)}; // Create new pointer "make_shared"
std::cout << *ptr1 << std::endl;
std::shared_ptr<float> ptr2{std::move(ptr1)}; // Data type "unique_ptr"
std::cout << *ptr2 << std::endl;
std::cout << (ptr1 == nullptr ? "ptr1 is null" : "ptr1 is not null") << std::endl;
return 0;
}