-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathproxy.cpp
169 lines (137 loc) · 4.03 KB
/
proxy.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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#include <cstdint>
#include <iostream>
#include <string>
#include <memory>
#include <utility>
// ------------------- PROPERTY PROXY ------------------- //
/*!
* @brief : PROPERTY PROXY
* Allow you to perform additional actions
* (For example, log or intercept) on properties
* access by a client without him seeing any difference.
*/
template<typename T>
class PropertyProxy {
public:
PropertyProxy(const T& p_val) : m_val(p_val) { }
~PropertyProxy() = default;
// Allow conversion to T
operator T() const { return m_val; }
// Allow conversion from T
T operator= (const T& p_val) { return m_val = p_val; }
private:
T m_val;
};
class ClassWithProperties {
public:
ClassWithProperties (
uint32_t p_prop1 = 0,
uint32_t p_prop2 = 0 ) :
m_prop1 (p_prop1),
m_prop2 (p_prop2) {}
~ClassWithProperties() = default;
public:
PropertyProxy<uint32_t> m_prop1;
PropertyProxy<uint32_t> m_prop2 ;
};
// ------------------- VIRTUAL PROXY ------------------- //
/*!
* @brief : VIRTUAL PROXY
* Allow you to perform lazy initializations
* to not waste memory without the client to
* even know about it.
*/
class IPicture {
public:
IPicture(std::string p_fileName = ""): m_fileName(p_fileName) {}
virtual void draw(void) = 0;
std::string getSrcFile(void) const { return m_fileName; }
protected:
// Assuming images will always be loaded from a file
std::string m_fileName;
};
class JpgPicture : public IPicture {
public:
JpgPicture(std::string p_fileName = "") : IPicture(std::move(p_fileName))
{
/*
* Actually perform the loading of the image eventho
* we might never use it !
*/
std::cout << "\tLoading the JPEG picture from file " << m_fileName << std::endl;
// Do the job
// ...
}
void draw(void) override
{
// All we have to do it to draw
std::cout << "\tDrawing image loaded from " << m_fileName << std::endl;
// Draw the image
}
};
class JpgLazyPicture : public IPicture {
public:
JpgLazyPicture(std::string p_fileName = "") : IPicture(std::move(p_fileName))
{
// We do not load the image yet since nobody asked for it yet...
}
void draw(void) override
{
// We load the image now if this is the first request
if ( !m_jpg ) { m_jpg = std::make_unique<JpgPicture>(m_fileName); }
// And then rely on JpgPicture to draw it
m_jpg->draw();
}
private:
std::unique_ptr<JpgPicture> m_jpg;
};
// ------------------- COMMUNICATION PROXY ------------------- //
/*!
* @brief : COMMUNICATION PROXY
* FROM http://www.vishalchovatiya.com/proxy-design-pattern-in-modern-cpp/#Property_Proxy
*/
template <typename T>
struct arr2D {
struct proxy {
proxy(T *arr) : m_arr_1D(arr) {}
T &operator[](int32_t idx) {
return m_arr_1D[idx];
}
T *m_arr_1D;
};
arr2D::proxy operator[](int32_t idx) {
return arr2D::proxy(m_arr_2D[idx]);
}
T m_arr_2D[10][10];
};
/*!
* @brief CLIENT CODE
*/
int main() {
// -------- Property proxy -------- //
{
/* The client will use the ClassWithProperties just
* as if those properties actually were of their
* base type (i.e. uint32_t)
*/
ClassWithProperties anObject(10, 5);
anObject.m_prop1 = 20;
anObject.m_prop2 = 8;
std::cout << anObject.m_prop1 << std::endl;
std::cout << anObject.m_prop2 << std::endl;
}
// -------- Virtual proxy -------- //
{
JpgLazyPicture jpgLazy("myJpg.jpg");
JpgPicture jpgBase("myJpg.jpg");
std::cout << "At this point, only jpgBase object has been loaded..." << std::endl;
std::cout << "Now let's ask for jpgLazy..." << std::endl;
jpgLazy.draw();
}
// ---- Communication proxy ---- //
{
arr2D<int32_t> arr;
arr[0][0] = 1; // Uses the proxy object
}
return 0;
}