0% found this document useful (0 votes)
11 views2 pages

Unique PTR

The document defines a unique pointer class template UP that manages dynamically allocated memory. It provides constructor, destructor, assignment operators and other methods to support move semantics. The make_unique function template is also defined to simplify unique pointer creation. Examples demonstrate using UP to manage class objects derived from a base class.

Uploaded by

GauravVasishtha
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views2 pages

Unique PTR

The document defines a unique pointer class template UP that manages dynamically allocated memory. It provides constructor, destructor, assignment operators and other methods to support move semantics. The make_unique function template is also defined to simplify unique pointer creation. Examples demonstrate using UP to manage class objects derived from a base class.

Uploaded by

GauravVasishtha
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 2

#include <iostream>

#include <utility>

template <typename T>


class UP {
private:
T* ptr;
public:
UP() : ptr(nullptr) {}
UP(nullptr_t) : ptr(nullptr){}
explicit UP(T* rawPtr) : ptr(rawPtr) {}
~UP() { delete ptr;}
UP(const UP&) = delete;
UP& operator=(const UP&) = delete;
UP(UP&& other) noexcept : ptr(other.ptr) {other.ptr = nullptr;}
template<typename U>
UP(UP<U>&& other) noexcept : ptr(other.release()) {}
UP& operator=(UP&& other) noexcept {
if (this != &other) {
delete ptr;
ptr = other.ptr;
other.ptr = nullptr;
}
return *this;
}
template<typename U>
UP& operator=(UP<U>&& other) noexcept {
delete ptr;
ptr = other.get();
other.reset();
return *this;
}
T& operator*() const { return *ptr; }
T* operator->() const {return ptr;}
T* get() const {return ptr;}
T* release() {
T* temp = ptr;
ptr = nullptr;
return temp;
}
void reset(T* rawPtr = nullptr) {
delete ptr;
ptr = rawPtr;
}
friend bool operator==(const UP& lhs, const UP& rhs) {return lhs.get() ==
rhs.get();}

friend bool operator!=(const UP& lhs, const UP& rhs) {return !(lhs == rhs);}
};

template <typename T, typename... Args>


UP<T> make_unique(Args&&... args) {
return UP<T>(new T(std::forward<Args>(args)...));
}
// Example usage
class Base {
public:
virtual void print() const {
std::cout << "Base class\n";
}
};

class Derived : public Base {


public:
void print() const override {
std::cout << "Derived class\n";
}
};

int main() {
// Create a UP to a Derived object
UP<Base> ok(new Base);
UP<Derived> basePtr = make_unique<Derived>();
ok = std::move(basePtr);
// Use the managed object
ok->print();

// Transfer ownership to another UP


/* UP<Base> anotherBasePtr = std::move(basePtr);

// Now basePtr is nullptr


if (!basePtr.get()) {
std::cout << "basePtr is nullptr\n";
}
if(basePtr!=anotherBasePtr)
std::cout<<"Wokrs\n";
// Reset basePtr and assign a new Derived object
basePtr.reset(make_unique<Derived>().release());
basePtr->print();*/
return 0;
}

You might also like