-
Notifications
You must be signed in to change notification settings - Fork 548
/
Copy path07_homework_03_answer.cpp
123 lines (88 loc) · 3.13 KB
/
07_homework_03_answer.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
#include <bits/stdc++.h>
using namespace std;
/*
- Saying that we need only ONE instance from this class, may trigger what?
- Static object: Shared object among all instances
- Now let's create a static instance to be shared
- But still users can create objects!
- The trick is to make the class constructor private!
- This way no one can create objects!
- But???? Ok, give him a function to return your static object
- You just learned Singleton Design Pattern :)
*/
class ConfigurationManger {
private:
string configuration_path;
vector<string> servers_ips;
string aws_service_url;
// Other heavy data
bool is_loaded = false;
// Private constructor! No one can create instances of this time (or even default one)
ConfigurationManger(string configuration_path) :
configuration_path(configuration_path) {
}
// Our shared instance
static ConfigurationManger* conf_mgr;
public:
// Give public method to return the static (shared) instance
static ConfigurationManger *GetInstance(const std::string& value) {
// Be careful: initialize once
if (conf_mgr == nullptr) {
cout << "Creating a new ConfigurationManger\n";
conf_mgr = new ConfigurationManger(value);
}
return conf_mgr;
}
void Load() {
if (is_loaded)
return;
// some heavy load
cout << "Lazy loading\n"; // what is lazy loading? Google
servers_ips.push_back("10.20.30.40");
servers_ips.push_back("10.20.30.41");
servers_ips.push_back("10.20.30.42");
aws_service_url = "https://dynamodb.us-west-2.amazonaws.com"; // what is Amazon AWS?
is_loaded = true;
}
string GetAwsServiceUrl() { // why not const?
Load();
return aws_service_url;
}
~ConfigurationManger() {
// Note, you shouldn't try to destroy the conf_mgr here!!!
// The first object destroy it but others still use it (or will reload)!
//FreeInstance(); // if you uncommented = infinite loop. WHY? Answer is belo very bottom
// Quote: Don’t create problems to solve a problem
}
static void FreeInstance() {
if (ConfigurationManger::conf_mgr != nullptr) {
cout << "Free the instance\n";
delete ConfigurationManger::conf_mgr;
ConfigurationManger::conf_mgr = nullptr;
} else
cout << "The instance freed already\n";
}
};
ConfigurationManger* ConfigurationManger::conf_mgr = nullptr;
void f1() {
ConfigurationManger* mgr = ConfigurationManger::GetInstance("/home/moustafa/conf_info.txt");
cout << mgr->GetAwsServiceUrl() << "\n";
}
void f2() {
ConfigurationManger* mgr = ConfigurationManger::GetInstance("/home/moustafa/conf_info.txt");
cout << mgr->GetAwsServiceUrl() << "\n";
}
int main() {
f1();
f2();
// If we forgot to free, it will be memory leak!
// We need more elegant solutions!
ConfigurationManger::FreeInstance();
return 0;
}
// Because destrctor calls destrctor calls destrctor to infinity
// How
// Scope of an object ended, so it calls ~ConfigurationManger(), which calls FreeInstance()
// FreeInstance does: delete ConfigurationManger::conf_mgr; => which is calling the destructor!
// Which repeat the same!
// Hell :)