Skip to content

Pointers

shared_ptr and unique_ptr are parts of the C++ standard library. They provide a safer way to manage pointers. The dynamically allocated objects will be destroyed when these pointers goes out of scope.

nullptr

nullptr was introduced to solve the ambiguity of NULL and 0. It is a prvalue, a pure rvalue. It can only exist as an rvalue. It is of type std::nullptr_t.

It provides type safety. So, there is no ambiguity when you call a overloaded function with it. However, if you call it with 0 or NULL, the could be either int or char.

unique_ptr

// A function that returns a unique_ptr to a newly created object.
std::unique_ptr<MyClass> createMyClass() {

    // Use make_unique to create one.
    std::unique_ptr<MyClass> ptr1 = std::make_unique<MyClass>();

    // std::unique_ptr<MyClass> ptr2 = ptr1; // This would cause a compile-time error
    std::unique_ptr<MyClass> ptr2 = std::move(ptr1); // Ownership is moved

    // ptr1 becomes nullptr.
    if (ptr1 == nullptr) {
        std::cout << "ptr1 is now null" << std::endl;
    }

    // Create another object ptr3.
    std::unique_ptr<MyClass> ptr3 = std::make_unique<MyClass>();

    // Do not use std::move when returning. The ownership is automatically
    // transferred.
    return ptr2;
    // MyClass is destroyed when ptr3 goes out of scope
}

When passing a unique_ptr as a parameter to a function, you either need to pass by reference, or using std::move. However, if using std::move, the object will be destroyed at the end of the function if you don't return it back.

shared_ptr

shared_ptr is much simpler, it allows multiple pointers to point to the same object. So, no std::move is needed. It uses std::make_shared<MyClass>(); to create.

Dereferenced pointers: referring to the value that a pointer is pointing to.

.release()

It releases the ownership from unique_ptr and can give the ownership to a plain pointer like int*.

std::unique_ptr<int> p1 = std::make_unique<int>(10);
int* raw_ptr = p1.release();
std::unique_ptr<int> p2(raw_ptr); // The new unique_ptr takes ownership.
// p1 is now null. p2 owns the memory.