|
/****************************************************************************** |
|
|
|
Online C++ Compiler. |
|
Code, Compile, Run and Debug C++ program online. |
|
Write your code in this editor and press "Run" button to compile and execute it. |
|
|
|
*******************************************************************************/ |
|
|
|
#include <iostream> |
|
#include <atomic> |
|
#include <utility> |
|
|
|
template <typename T> |
|
class SharedPtr { |
|
private: |
|
|
|
T* ptr; |
|
std::atomic<unsigned>* ref_count; |
|
|
|
void release() { |
|
if (ref_count) { |
|
if (--(*ref_count) == 0) { |
|
delete ptr; |
|
delete ref_count; |
|
} |
|
} |
|
} |
|
|
|
public: |
|
|
|
SharedPtr() : ptr(nullptr), ref_count(nullptr) {} |
|
|
|
explicit SharedPtr(T* raw_ptr) : ptr(raw_ptr), ref_count(new std::atomic<unsigned>(1)) { |
|
} |
|
|
|
// Copy constructor |
|
SharedPtr(const SharedPtr& other) : ptr(other.ptr), ref_count(other.ref_count) { |
|
if (ref_count) { |
|
++(*ref_count); |
|
} |
|
} |
|
|
|
// Move constructor |
|
SharedPtr(SharedPtr&& other) noexcept : ptr(other.ptr), ref_count(other.ref_count) { |
|
other.ptr = nullptr; |
|
other.ref_count = nullptr; |
|
} |
|
|
|
// Copy assignment operator |
|
SharedPtr& operator=(const SharedPtr& other) { |
|
if (this != other) { |
|
release(); |
|
ptr = other.ptr; |
|
ref_count = other.ref_count; |
|
if (ref_count) { |
|
++(*ref_count); |
|
} |
|
} |
|
return *this; |
|
} |
|
|
|
// Move assignment operator |
|
SharedPtr& operator=(SharedPtr&& other) noexcept { |
|
if (this != &other) { |
|
release(); |
|
ptr = other.ptr; |
|
ref_count = other.ref_count; |
|
other.ptr = nullptr; |
|
other.ref_count = nullptr; |
|
} |
|
} |
|
|
|
~SharedPtr() { |
|
release(); |
|
} |
|
|
|
unsigned use_count() const { |
|
return ref_count ? ref_count->load() : 0; |
|
} |
|
|
|
}; |
|
|
|
int main() |
|
{ |
|
SharedPtr<int> sp1(new int(10)); |
|
std::cout << "Reference count: " << sp1.use_count() << "\n"; |
|
|
|
{ |
|
SharedPtr<int> sp2 = sp1; // Copy constructor |
|
std::cout << "Reference count after copy: " << sp1.use_count() << "\n"; |
|
|
|
SharedPtr<int> sp3 = std::move(sp1); // Move constructor |
|
std::cout << "Reference count after move: " << sp3.use_count() << "\n"; |
|
} |
|
|
|
std::cout << "Reference count after block: " << sp1.use_count() << "\n"; |
|
|
|
return 0; |
|
} |