#include <iostream>
#include <memory>

class Entity {
public:
    Entity(int val) : value(val) {
        std::cout << "Entity Created with value: " << value << "\n";
    }
    ~Entity() {
        std::cout << "Entity Destroyed with value: " << value << "\n";
    }
    int value;
};

// Function demonstrating shared_ptr usage and copying behavior
void sharedPointerExample() {
    std::shared_ptr<Entity> sp1 = std::make_shared<Entity>(1); // Create Entity with shared ownership
    std::cout << "Shared pointer count: " << sp1.use_count() << "\n"; // Output: 1

    {
        // Copying the shared_ptr (sp2 now shares ownership with sp1)
        std::shared_ptr<Entity> sp2 = sp1; // sp2 is a copy of sp1
        // Reference count increments to 2
        std::cout << "Shared pointer count inside block: " << sp1.use_count() << "\n"; // Output: 2
    } // sp2 goes out of scope, reference count decrements to 1

    std::cout << "Shared pointer count after block: " << sp1.use_count() << "\n"; // Output: 1
} // sp1 goes out of scope, Entity is destroyed

// Function demonstrating weak_ptr usage and checking its validity
void weakPointerExample() {
    // shared_ptr to manage an Entity with value 2
    std::shared_ptr<Entity> sp1 = std::make_shared<Entity>(2);

    // weak_ptr observes sp1’s managed object without taking ownership
    std::weak_ptr<Entity> wp = sp1;

    // weak_ptr does not increase the reference count
    std::cout << "Shared pointer count (with weak_ptr observing): " << sp1.use_count() << "\n"; // Output: 1

    // Lock weak_ptr to safely access the object (converts to shared_ptr)
    if (auto sp2 = wp.lock()) { // Only valid if object still exists
        std::cout << "Weak pointer locked, value: " << sp2->value << "\n";
    }

    sp1.reset(); // Release ownership of Entity, so it is destroyed now

    // Check if weak_ptr is expired (object destroyed)
    if (wp.expired()) {
        std::cout << "Entity destroyed, weak pointer is expired\n";
    }
}

// Function demonstrating unique_ptr usage and non-copyable behavior
void uniquePointerExample() {
    std::unique_ptr<Entity> up1 = std::make_unique<Entity>(3);
    std::cout << "Unique pointer value: " << up1->value << "\n";

    // Unique pointers cannot be copied, only moved:
    // std::unique_ptr<Entity> up2 = up1; // Error: copy not allowed
    std::unique_ptr<Entity> up2 = std::move(up1); // Transfer ownership to up2

    if (!up1) { // up1 no longer owns the Entity
        std::cout << "Unique pointer ownership transferred, up1 is now nullptr\n";
    }
    std::cout << "Unique pointer 2 value: " << up2->value << "\n";
} // up2 goes out of scope, and the Entity is destroyed

int main() {
    std::cout << "=== Shared Pointer Example ===\n";
    sharedPointerExample();

    std::cout << "\n=== Weak Pointer Example ===\n";
    weakPointerExample();

    std::cout << "\n=== Unique Pointer Example ===\n";
    uniquePointerExample();

    return 0;
}

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: