└── shared_ptr.cpp /shared_ptr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | void AdvancedSharedPtr(); // Forward reference 8 | void FileExample(); // Forward reference 9 | void WeakPtrDemo(); // Forward reference 10 | 11 | class Base { 12 | public: 13 | virtual void speak() { 14 | std::cout << "I am a Base." << std::endl; 15 | } 16 | 17 | virtual ~Base() { 18 | std::cout << "Base destroyed." << std::endl; 19 | } 20 | }; 21 | 22 | class Derived : public Base { 23 | public: 24 | void speak() override { 25 | std::cout << "I am a Derived." << std::endl; 26 | } 27 | 28 | ~Derived() override { 29 | std::cout << "Derived destroyed." << std::endl; 30 | } 31 | }; 32 | 33 | void custom_deleter(Base *ptr) { 34 | std::cout << "Custom deleter called." << std::endl; 35 | delete ptr; 36 | } 37 | 38 | int main() 39 | { 40 | // Creating a shared_ptr and initializing it with a new object 41 | std::shared_ptr sp1 = std::make_shared(); 42 | sp1->speak(); 43 | 44 | // Creating a shared_ptr with a custom deleter 45 | std::shared_ptr sp2(new Derived, custom_deleter); 46 | sp2->speak(); 47 | 48 | // Creating a shared_ptr from another shared_ptr (copying) 49 | std::shared_ptr sp3 = sp1; 50 | sp3->speak(); 51 | 52 | // Resetting a shared_ptr 53 | sp3.reset(new Derived); 54 | sp3->speak(); 55 | 56 | // Checking the use_count of a shared_ptr 57 | std::cout << "sp1 use_count: " << sp1.use_count() << std::endl; 58 | 59 | // Using shared_ptr in a container 60 | std::vector> container; 61 | container.push_back(sp1); 62 | container.push_back(sp2); 63 | container.push_back(sp3); 64 | 65 | for (const auto &item : container) { 66 | item->speak(); 67 | } 68 | 69 | AdvancedSharedPtr(); 70 | WeakPtrDemo(); 71 | 72 | return 0; 73 | } 74 | 75 | //------------------------------------------------------------------------- 76 | // Advanced shared_ptr examples 77 | //------------------------------------------------------------------------- 78 | 79 | void AdvancedSharedPtr() 80 | { 81 | // 1. Weak pointers 82 | std::shared_ptr sp1 = std::make_shared(); 83 | std::weak_ptr wp1 = sp1; 84 | 85 | if (std::shared_ptr locked = wp1.lock()) { 86 | locked->speak(); 87 | } 88 | 89 | sp1.reset(); 90 | 91 | if (wp1.expired()) { 92 | std::cout << "The weak_ptr is expired." << std::endl; 93 | } 94 | 95 | // 2. Aliasing constructor 96 | std::shared_ptr sp2 = std::make_shared(); 97 | std::shared_ptr sp2_alias(sp2, sp2.get()); 98 | sp2_alias->speak(); 99 | std::cout << "sp2 use_count: " << sp2.use_count() << std::endl; 100 | 101 | // 3. shared_ptr for arrays 102 | std::shared_ptr sp3(new Base[3]); 103 | sp3[0].speak(); 104 | sp3[1].speak(); 105 | sp3[2].speak(); 106 | 107 | // 4. Atomic operations 108 | std::shared_ptr sp4 = std::make_shared(); 109 | std::shared_ptr sp5; 110 | 111 | std::thread t1([&]() { 112 | std::atomic_store(&sp5, std::atomic_load(&sp4)); 113 | }); 114 | 115 | std::thread t2([&]() { 116 | std::atomic_store(&sp4, std::shared_ptr(nullptr)); 117 | }); 118 | 119 | t1.join(); 120 | t2.join(); 121 | 122 | if (sp5) { 123 | sp5->speak(); 124 | } 125 | } 126 | 127 | //------------------------------------------------------------------------- 128 | // Custom deleter example for FILE objects 129 | //------------------------------------------------------------------------- 130 | 131 | void file_deleter(FILE *file) { 132 | if (file) { 133 | std::cout << "Closing the file." << std::endl; 134 | fclose(file); 135 | } 136 | } 137 | 138 | void readFile(const char *filename) { 139 | // Create a shared_ptr with a custom deleter 140 | std::shared_ptr file(fopen(filename, "r"), file_deleter); 141 | 142 | if (!file) { 143 | std::cerr << "Failed to open the file." << std::endl; 144 | return; 145 | } 146 | 147 | // Read the file 148 | char buffer[256]; 149 | while (fgets(buffer, sizeof(buffer), file.get()) != nullptr) { 150 | std::cout << buffer; 151 | } 152 | 153 | // The file will be closed automatically by the custom deleter 154 | } 155 | 156 | void FileExample() 157 | { 158 | readFile("main.cpp"); 159 | } 160 | 161 | //------------------------------------------------------------------------- 162 | // Weak pointer demo 163 | //------------------------------------------------------------------------- 164 | 165 | void WeakPtrDemo() 166 | { 167 | // Create a shared_ptr and initialize it with a new object 168 | std::shared_ptr sp1 = std::make_shared(); 169 | 170 | // Create a weak_ptr from the shared_ptr 171 | std::weak_ptr wp1(sp1); 172 | 173 | // Check if the weak_ptr is valid and lock it to obtain a shared_ptr 174 | if (auto locked = wp1.lock()) { 175 | std::cout << "Weak pointer is valid. Locked and obtained shared_ptr." << std::endl; 176 | locked->speak(); 177 | } else { 178 | std::cout << "Weak pointer is not valid." << std::endl; 179 | } 180 | 181 | // Reset the shared_ptr, causing the object to be destroyed 182 | sp1.reset(); 183 | 184 | // Check if the weak_ptr is still valid 185 | if (wp1.expired()) { 186 | std::cout << "Weak pointer is now expired." << std::endl; 187 | } else { 188 | std::cout << "Weak pointer is still valid." << std::endl; 189 | } 190 | } --------------------------------------------------------------------------------