/*
Implementing your own version of std::unique_ptr in C++ involves creating a
class that takes ownership of a dynamically allocated resource and ensures
that the resource is properly deallocated when the unique_ptr goes out of
scope.
This MyUniquePtr class mimics the behavior of std::unique_ptr.
It has move semantics, disallows copy operations, and ensures that the
owned resource is properly deallocated when the MyUniquePtr goes out
of scope.
*/
#include <iostream>
template <typename T>
class MyUniquePtr {
private:
T* ptr;
public:
// Constructor
explicit MyUniquePtr(T* p = nullptr) : ptr(p) {}
// Destructor
~MyUniquePtr() {
delete ptr;
}
// Disable copy constructor and copy assignment
MyUniquePtr(const MyUniquePtr&) = delete;
MyUniquePtr& operator=(const MyUniquePtr&) = delete;
// Move constructor
MyUniquePtr(MyUniquePtr&& other) noexcept : ptr(other.ptr) {
other.ptr = nullptr;
}
// Move assignment
MyUniquePtr& operator=(MyUniquePtr&& other) noexcept {
if (this != &other) {
delete ptr;
ptr = other.ptr;
other.ptr = nullptr;
}
return *this;
}
// Dereference operator
T& operator*() const {
return *ptr;
}
// Member access operator
T* operator->() const {
return ptr;
}
// Release ownership
T* release() {
T* releasedPtr = ptr;
ptr = nullptr;
return releasedPtr;
}
// Reset pointer
void reset(T* p = nullptr) {
delete ptr;
ptr = p;
}
// Get raw pointer
T* get() const {
return ptr;
}
// Boolean conversion for conditional checks
explicit operator bool() const {
return ptr != nullptr;
}
};
// Example usage
int main() {
MyUniquePtr<int> myUniquePtr(new int(42));
if (myUniquePtr) {
std::cout << "Value: " << *myUniquePtr << std::endl;
}
MyUniquePtr<int> anotherUniquePtr = std::move(myUniquePtr);
if (!myUniquePtr) {
std::cout << "myUniquePtr is now null" << std::endl;
}
return 0;
}