#include <iostream>
#include <memory>

class Resource {
public:
    Resource(int value) : data(value) {
        std::cout << "Resource acquired: " << data << std::endl;
    }
    ~Resource() {
        std::cout << "Resource destroyed: " << data << std::endl;
    }
    void use() {
        std::cout << "Using resource: " << data << std::endl;
    }
private:
    int data;
};

void uniquePtrExample() {
    std::cout << "unique_ptr example:" << std::endl;
    std::unique_ptr<Resource> uniqueRes = std::make_unique<Resource>(1);
    uniqueRes->use();
    // uniqueRes will be automatically deleted when it goes out of scope
}

void sharedPtrExample() {
    std::cout << "\nshared_ptr example:" << std::endl;
    std::shared_ptr<Resource> sharedRes1 = std::make_shared<Resource>(2);
    {
        std::shared_ptr<Resource> sharedRes2 = sharedRes1;
        std::cout << "Resource count: " << sharedRes1.use_count() << std::endl;
        sharedRes2->use();
    }
    std::cout << "Resource count after inner scope: " << sharedRes1.use_count() << std::endl;
    // sharedRes1 will be deleted when the last shared_ptr goes out of scope
}

void weakPtrExample() {
    std::cout << "\nweak_ptr example:" << std::endl;
    std::shared_ptr<Resource> sharedRes = std::make_shared<Resource>(3);
    std::weak_ptr<Resource> weakRes = sharedRes;
    
    if (auto tempShared = weakRes.lock()) {
        tempShared->use();
    } else {
        std::cout << "Resource no longer available" << std::endl;
    }
    
    sharedRes.reset();  // Explicitly release the resource
    
    if (auto tempShared = weakRes.lock()) {
        tempShared->use();
    } else {
        std::cout << "Resource no longer available" << std::endl;
    }
}

int main() {
    uniquePtrExample();
    sharedPtrExample();
    weakPtrExample();
    return 0;
} 
by