C++智能指针编程实例

发布于:2025-06-23 ⋅ 阅读:(21) ⋅ 点赞:(0)

智能指针是C++11引入的重要特性,用于自动管理动态分配的内存,防止内存泄漏。下面介绍几种高级智能指针编程实例。

1. 共享所有权模式 (shared_ptr)

循环引用问题及解决方案

#include <memory>
#include <iostream>

class B; // 前向声明

class A {
public:
    std::shared_ptr<B> b_ptr;
    ~A() { std::cout << "A destroyed\n"; }
};

class B {
public:
    std::shared_ptr<A> a_ptr; // 这里会导致循环引用
    ~B() { std::cout << "B destroyed\n"; }
};

void circularReferenceProblem() {
    auto a = std::make_shared<A>();
    auto b = std::make_shared<B>();
    a->b_ptr = b;
    b->a_ptr = a; // 循环引用
    // 离开作用域时,a和b不会被销毁
}

// 使用weak_ptr解决循环引用
class B_fixed;

class A_fixed {
public:
    std::shared_ptr<B_fixed> b_ptr;
    ~A_fixed() { std::cout << "A_fixed destroyed\n"; }
};

class B_fixed {
public:
    std::weak_ptr<A_fixed> a_ptr; // 使用weak_ptr打破循环
    ~B_fixed() { std::cout << "B_fixed destroyed\n"; }
};

void circularReferenceSolution() {
    auto a = std::make_shared<A_fixed>();
    auto b = std::make_shared<B_fixed>();
    a->b_ptr = b;
    b->a_ptr = a; // weak_ptr不会增加引用计数
    // 离开作用域时,a和b会被正确销毁
}

2. 独占所有权模式 (unique_ptr)

工厂模式应用

#include <memory>
#include <iostream>

class Base {
public:
    virtual void doSomething() = 0;
    virtual ~Base() = default;
};

class Derived1 : public Base {
public:
    void doSomething() override {
        std::cout << "Derived1 doing something\n";
    }
};

class Derived2 : public Base {
public:
    void doSomething() override {
        std::cout << "Derived2 doing something\n";
    }
};

enum class ProductType { TYPE1, TYPE2 };

std::unique_ptr<Base> createProduct(ProductType type) {
    switch(type) {
        case ProductType::TYPE1: return std::make_unique<Derived1>();
        case ProductType::TYPE2: return std::make_unique<Derived2>();
        default: return nullptr;
    }
}

void factoryPatternExample() {
    auto product1 = createProduct(ProductType::TYPE1);
    auto product2 = createProduct(ProductType::TYPE2);
    
    product1->doSomething();
    product2->doSomething();
    
    // unique_ptr会自动管理内存
}

3. 弱引用模式 (weak_ptr)

缓存系统实现

#include <memory>
#include <unordered_map>
#include <iostream>

class ExpensiveResource {
public:
    ExpensiveResource(int id) : id(id) {
        std::cout << "Creating resource " << id << "\n";
    }
    ~ExpensiveResource() {
        std::cout << "Destroying resource " << id << "\n";
    }
    void use() {
        std::cout << "Using resource " << id << "\n";
    }
private:
    int id;
};

class ResourceCache {
public:
    std::shared_ptr<ExpensiveResource> getResource(int id) {
        std::shared_ptr<ExpensiveResource> res;
        
        auto it = cache.find(id);
        if (it != cache.end()) {
            res = it->second.lock(); // 尝试从weak_ptr获取shared_ptr
        }
        
        if (!res) {
            res = std::make_shared<ExpensiveResource>(id);
            cache[id] = res; // 存储weak_ptr
        }
        
        return res;
    }
    
    size_t size() const { return cache.size(); }
    
private:
    std::unordered_map<int, std::weak_ptr<ExpensiveResource>> cache;
};

void cacheExample() {
    ResourceCache cache;
    {
        auto res1 = cache.getResource(1);
        auto res2 = cache.getResource(2);
        res1->use();
        res2->use();
        
        std::cout << "Cache size: " << cache.size() << "\n";
    }
    
    // 资源已释放,但缓存中仍有weak_ptr
    std::cout << "Cache size after resources out of scope: " << cache.size() << "\n";
    
    // 再次获取资源1,会创建新实例
    auto res1_again = cache.getResource(1);
    res1_again->use();
}

4. 自定义删除器

文件指针管理

#include <memory>
#include <cstdio>

void fileDeleter(FILE* file) {
    if (file) {
        std::fclose(file);
        std::cout << "File closed\n";
    }
}
void customDeleterExample() {
    // 使用自定义删除器管理文件指针
    std::unique_ptr<FILE, decltype(&fileDeleter)> filePtr(
        std::fopen("example.txt", "w"), 
        &fileDeleter
    );
    
    if (filePtr) {
        std::fputs("Hello, world!", filePtr.get());
    }
    // 离开作用域时自动调用fileDeleter关闭文件
}

5. 多态与智能指针

多态对象管理

#include <memory>
#include <vector>
#include <iostream>

class Animal {
public:
    virtual void speak() const = 0;
    virtual ~Animal() = default;
};

class Dog : public Animal {
public:
    void speak() const override {
        std::cout << "Woof!\n";
    }
};

class Cat : public Animal {
public:
    void speak() const override {
        std::cout << "Meow!\n";
    }
};

void polymorphismExample() {
    std::vector<std::unique_ptr<Animal>> animals;
    
    animals.push_back(std::make_unique<Dog>());
    animals.push_back(std::make_unique<Cat>());
    
    for (const auto& animal : animals) {
        animal->speak();
    }
    
    // unique_ptr会自动调用正确的析构函数
}

6. 共享指针与弱指针结合

观察者模式实现

#include <memory>
#include <vector>
#include <iostream>
#include <algorithm>

class Observer;

class Subject {
public:
    void attach(std::weak_ptr<Observer> observer) {
        observers.push_back(observer);
    }
    
    void notifyAll();
    
private:
    std::vector<std::weak_ptr<Observer>> observers;
};

class Observer : public std::enable_shared_from_this<Observer> {
public:
    Observer(std::shared_ptr<Subject> subject) : subject(subject) {
        subject->attach(weak_from_this());
    }
    
    virtual void update() = 0;
    virtual ~Observer() = default;
    
protected:
    std::shared_ptr<Subject> subject;
};

void Subject::notifyAll() {
    for (auto it = observers.begin(); it != observers.end(); ) {
        if (auto observer = it->lock()) {
            observer->update();
            ++it;
        } else {
            it = observers.erase(it);
        }
    }
}

class ConcreteObserver : public Observer {
public:
    using Observer::Observer;
    
    void update() override {
        std::cout << "Observer notified!\n";
    }
};

void observerPatternExample() {
    auto subject = std::make_shared<Subject>();
    auto observer1 = std::make_shared<ConcreteObserver>(subject);
    auto observer2 = std::make_shared<ConcreteObserver>(subject);
    
    subject->notifyAll();
    
    // 当observer超出作用域时,weak_ptr会自动失效
}

7. 智能指针与多线程

线程安全共享数据

#include <memory>
#include <thread>
#include <vector>
#include <mutex>
#include <iostream>

class ThreadSafeData {
public:
    void add(int value) {
        std::lock_guard<std::mutex> lock(mutex);
        data.push_back(value);
    }
    
    void print() const {
        std::lock_guard<std::mutex> lock(mutex);
        for (int val : data) {
            std::cout << val << " ";
        }
        std::cout << "\n";
    }
    
private:
    mutable std::mutex mutex;
    std::vector<int> data;
};

void worker(std::shared_ptr<ThreadSafeData> data, int id) {
    for (int i = 0; i < 5; ++i) {
        data->add(id * 100 + i);
    }
}

void threadSafeExample() {
    auto data = std::make_shared<ThreadSafeData>();
    std::vector<std::thread> threads;
    
    for (int i = 0; i < 3; ++i) {
        threads.emplace_back(worker, data, i + 1);
    }
    
    for (auto& t : threads) {
        t.join();
    }
    
    data->print();
}

8. 智能指针与STL容器

容器中存储智能指针

#include <memory>
#include <vector>
#include <iostream>

class Item {
public:
    Item(int id) : id(id) {
        std::cout << "Item " << id << " created\n";
    }
    ~Item() {
        std::cout << "Item " << id << " destroyed\n";
    }
    void use() {
        std::cout << "Using item " << id << "\n";
    }
private:
    int id;
};

void stlContainerExample() {
    std::vector<std::shared_ptr<Item>> items;
    
    items.push_back(std::make_shared<Item>(1));
    items.push_back(std::make_shared<Item>(2));
    items.push_back(std::make_shared<Item>(3));
    
    // 复制智能指针会增加引用计数
    auto item2 = items[1];
    
    for (const auto& item : items) {
        item->use();
    }
    
    // 当items和item2超出作用域时,Item对象会被正确销毁
}

这些实例展示了C++智能指针在各种场景下的高级应用,包括内存管理、设计模式实现、多线程编程等。合理使用智能指针可以显著提高代码的安全性和可维护性。


网站公告

今日签到

点亮在社区的每一天
去签到