智能指针是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++智能指针在各种场景下的高级应用,包括内存管理、设计模式实现、多线程编程等。合理使用智能指针可以显著提高代码的安全性和可维护性。