21.1 智能指针基础

21.1.1 unique_ptr

#include <iostream>
#include <memory>
using namespace std;

class Resource {
public:
    Resource() { cout << "Resource acquired" << endl; }
    ~Resource() { cout << "Resource released" << endl; }
    void use() { cout << "Using resource" << endl; }
};

int main() {
    // unique_ptr:独占所有权
    unique_ptr<Resource> ptr1(new Resource());
    ptr1->use();

    // 移动所有权
    unique_ptr<Resource> ptr2 = move(ptr1);
    // ptr1现在为空

    // 使用make_unique(C++14)
    auto ptr3 = make_unique<Resource>();

    return 0;  // 自动释放资源
}

21.1.2 shared_ptr

#include <iostream>
#include <memory>
using namespace std;

int main() {
    // shared_ptr:共享所有权
    shared_ptr<int> ptr1 = make_shared<int>(42);
    cout << "ptr1引用计数:" << ptr1.use_count() << endl;

    {
        shared_ptr<int> ptr2 = ptr1;
        cout << "ptr1引用计数:" << ptr1.use_count() << endl;  // 2
        cout << "*ptr2 = " << *ptr2 << endl;
    }

    cout << "ptr1引用计数:" << ptr1.use_count() << endl;  // 1

    return 0;
}

21.1.3 weak_ptr

#include <iostream>
#include <memory>
using namespace std;

int main() {
    shared_ptr<int> sptr = make_shared<int>(100);
    weak_ptr<int> wptr = sptr;

    cout << "sptr引用计数:" << sptr.use_count() << endl;  // 1

    // 使用weak_ptr
    if (auto locked = wptr.lock()) {
        cout << "*locked = " << *locked << endl;
    }

    sptr.reset();  // 释放shared_ptr

    if (wptr.expired()) {
        cout << "对象已被销毁" << endl;
    }

    return 0;
}

21.2 RAII原则

#include <iostream>
#include <fstream>
#include <memory>
using namespace std;

class FileHandler {
private:
    unique_ptr<ifstream> file;

public:
    FileHandler(const string& filename) {
        file = make_unique<ifstream>(filename);
        if (!file->is_open()) {
            throw runtime_error("无法打开文件");
        }
    }

    void readData() {
        string line;
        while (getline(*file, line)) {
            cout << line << endl;
        }
    }

    // 析构函数自动关闭文件
    ~FileHandler() {
        if (file && file->is_open()) {
            file->close();
            cout << "文件已关闭" << endl;
        }
    }
};

int main() {
    try {
        FileHandler handler("data.txt");
        handler.readData();
    } catch (const exception& e) {
        cout << "错误:" << e.what() << endl;
    }

    return 0;
}

21.1 自定义删除器

21.1.1 unique_ptr的自定义删除器

#include <iostream>
#include <memory>
#include <cstdio>
using namespace std;

// 自定义删除器:函数
void fileDeleter(FILE* fp) {
    if (fp) {
        cout << "关闭文件" << endl;
        fclose(fp);
    }
}

// 自定义删除器:函数对象
class ArrayDeleter {
public:
    void operator()(int* ptr) const {
        cout << "删除数组" << endl;
        delete[] ptr;
    }
};

void demonstrateUniqueDeleter() {
    // 方式1:使用函数指针作为删除器
    {
        unique_ptr<FILE, decltype(&fileDeleter)> fp(
            fopen("test.txt", "w"),
            fileDeleter
        );
        // 文件会在fp销毁时自动关闭
    }

    // 方式2:使用Lambda作为删除器
    {
        auto deleter = [](int* ptr) {
            cout << "Lambda删除器" << endl;
            delete[] ptr;
        };

        unique_ptr<int, decltype(deleter)> ptr(
            new int[10],
            deleter
        );
    }

    // 方式3:使用函数对象
    {
        unique_ptr<int, ArrayDeleter> ptr(
            new int[10],
            ArrayDeleter()
        );
    }

    // 方式4:使用auto推导(C++17)
    {
        auto deleter = [](int* ptr) {
            delete[] ptr;
        };

        unique_ptr<int, decltype(deleter)> ptr(new int[10], deleter);
    }
}

int main() {
    demonstrateUniqueDeleter();
    return 0;
}

21.1.2 shared_ptr的自定义删除器

#include <iostream>
#include <memory>
#include <cstdio>
using namespace std;

// shared_ptr的删除器更灵活,不需要在类型中指定
void demonstrateSharedDeleter() {
    // 方式1:使用Lambda
    {
        shared_ptr<FILE> fp(
            fopen("test.txt", "w"),
            [](FILE* f) {
                if (f) {
                    cout << "Lambda关闭文件" << endl;
                    fclose(f);
                }
            }
        );
    }

    // 方式2:使用函数
    {
        auto deleter = [](int* ptr) {
            cout << "删除数组" << endl;
            delete[] ptr;
        };

        shared_ptr<int> ptr(new int[10], deleter);
    }

    // 方式3:使用std::default_delete
    {
        shared_ptr<int> ptr(new int[10], default_delete<int[]>());
    }

    // 方式4:使用自定义类
    {
        struct LoggingDeleter {
            void operator()(int* ptr) const {
                cout << "LoggingDeleter: 删除对象" << endl;
                delete ptr;
            }
        };

        shared_ptr<int> ptr(new int(42), LoggingDeleter());
    }
}

int main() {
    demonstrateSharedDeleter();
    return 0;
}

21.1.3 实际应用场景

#include <iostream>
#include <memory>
#include <cstdlib>
using namespace std;

// 场景1:管理C风格资源
class WindowsHandle {
public:
    static shared_ptr<void> create() {
        void* handle = malloc(100);  // 模拟Windows句柄

        return shared_ptr<void>(handle, [](void* h) {
            cout << "释放Windows句柄" << endl;
            free(h);
        });
    }
};

// 场景2:管理数据库连接
class DatabaseConnection {
private:
    int connectionId;

public:
    DatabaseConnection(int id) : connectionId(id) {
        cout << "打开数据库连接 " << connectionId << endl;
    }

    ~DatabaseConnection() {
        cout << "关闭数据库连接 " << connectionId << endl;
    }

    void execute(const string& sql) {
        cout << "执行SQL: " << sql << endl;
    }
};

shared_ptr<DatabaseConnection> createConnection(int id) {
    return shared_ptr<DatabaseConnection>(
        new DatabaseConnection(id),
        [](DatabaseConnection* conn) {
            // 自定义清理逻辑
            cout << "清理连接池..." << endl;
            delete conn;
        }
    );
}

// 场景3:管理OpenGL纹理
struct GLTexture {
    unsigned int id;
};

shared_ptr<GLTexture> createTexture() {
    GLTexture* texture = new GLTexture{42};

    return shared_ptr<GLTexture>(texture, [](GLTexture* tex) {
        cout << "删除OpenGL纹理: " << tex->id << endl;
        // glDeleteTextures(1, &tex->id);  // 实际的OpenGL调用
        delete tex;
    });
}

void demonstrateRealWorldUsage() {
    // 使用Windows句柄
    auto handle = WindowsHandle::create();

    // 使用数据库连接
    auto conn = createConnection(123);
    conn->execute("SELECT * FROM users");

    // 使用OpenGL纹理
    auto texture = createTexture();

    // 所有资源都会自动释放
}

int main() {
    demonstrateRealWorldUsage();
    return 0;
}

21.2 智能指针与this

21.2.1 enable_shared_from_this详解

#include <iostream>
#include <memory>
using namespace std;

// ❌ 错误:直接使用this创建shared_ptr
class BadClass {
public:
    shared_ptr<BadClass> getShared() {
        return shared_ptr<BadClass>(this);  // 危险!
    }
};

void demonstrateBadUsage() {
    shared_ptr<BadClass> p1 = make_shared<BadClass>();
    shared_ptr<BadClass> p2 = p1->getShared();

    // 问题:p1和p2各自管理this,会导致二次删除!
    cout << "p1引用计数: " << p1.use_count() << endl;  // 1
    cout << "p2引用计数: " << p2.use_count() << endl;  // 1
    // 销毁时会崩溃!
}

// ✅ 正确:使用enable_shared_from_this
class GoodClass : public enable_shared_from_this<GoodClass> {
public:
    shared_ptr<GoodClass> getShared() {
        return shared_from_this();  // 安全
    }
};

void demonstrateGoodUsage() {
    shared_ptr<GoodClass> p1 = make_shared<GoodClass>();
    shared_ptr<GoodClass> p2 = p1->getShared();

    cout << "p1引用计数: " << p1.use_count() << endl;  // 2
    cout << "p2引用计数: " << p2.use_count() << endl;  // 2
    // 正确共享所有权
}

int main() {
    // demonstrateBadUsage();  // 会崩溃,已注释
    demonstrateGoodUsage();

    return 0;
}

21.2.2 使用场景与陷阱

#include <iostream>
#include <memory>
#include <vector>
using namespace std;

// 场景1:异步回调
class AsyncTask : public enable_shared_from_this<AsyncTask> {
private:
    int taskId;

public:
    AsyncTask(int id) : taskId(id) {}

    void start() {
        // 启动异步任务,传递自身指针
        // 注意:必须在shared_ptr管理下才能调用shared_from_this
        auto self = shared_from_this();

        // 模拟异步操作
        cout << "启动任务 " << taskId << endl;

        // 在回调中使用self,确保对象不被提前销毁
    }
};

// 场景2:观察者模式
class Subject;

class Observer : public enable_shared_from_this<Observer> {
public:
    void subscribe(shared_ptr<Subject> subject);

    void notify(const string& message) {
        cout << "收到通知: " << message << endl;
    }
};

class Subject {
private:
    vector<weak_ptr<Observer>> observers;

public:
    void attach(shared_ptr<Observer> observer) {
        observers.push_back(observer);
    }

    void notifyAll(const string& message) {
        for (auto& weakObs : observers) {
            if (auto obs = weakObs.lock()) {
                obs->notify(message);
            }
        }
    }
};

void Observer::subscribe(shared_ptr<Subject> subject) {
    subject->attach(shared_from_this());
}

// ❌ 陷阱1:在构造函数中调用shared_from_this
class WrongUsage : public enable_shared_from_this<WrongUsage> {
public:
    WrongUsage() {
        // ❌ 错误:此时对象还未被shared_ptr管理
        // auto self = shared_from_this();  // 抛出异常!
    }

    void init() {
        // ✅ 正确:在初始化函数中调用
        auto self = shared_from_this();
    }
};

void demonstrateUsagePatterns() {
    // 正确的使用方式
    auto task = make_shared<AsyncTask>(1);
    task->start();

    // 观察者模式
    auto subject = make_shared<Subject>();
    auto observer1 = make_shared<Observer>();
    auto observer2 = make_shared<Observer>();

    observer1->subscribe(subject);
    observer2->subscribe(subject);

    subject->notifyAll("事件发生了");

    // 避免陷阱
    auto obj = make_shared<WrongUsage>();
    obj->init();  // 在构造后调用
}

int main() {
    demonstrateUsagePatterns();
    return 0;
}

21.2.3 weak_from_this (C++17)

#include <iostream>
#include <memory>
using namespace std;

class Node : public enable_shared_from_this<Node> {
private:
    int value;

public:
    Node(int v) : value(v) {}

    // 返回weak_ptr避免循环引用
    weak_ptr<Node> getWeakPtr() {
        return weak_from_this();  // C++17
    }

    void setValue(int v) { value = v; }
    int getValue() const { return value; }
};

void demonstrateWeakFromThis() {
    auto node = make_shared<Node>(42);

    weak_ptr<Node> weakNode = node->getWeakPtr();

    cout << "引用计数: " << node.use_count() << endl;  // 1

    if (auto locked = weakNode.lock()) {
        cout << "值: " << locked->getValue() << endl;
    }
}

int main() {
    demonstrateWeakFromThis();
    return 0;
}

21.3 循环引用问题深入

21.3.1 循环引用演示

#include <iostream>
#include <memory>
using namespace std;

// ❌ 问题:循环引用导致内存泄漏
class BadNode {
public:
    shared_ptr<BadNode> next;
    shared_ptr<BadNode> prev;

    ~BadNode() {
        cout << "BadNode析构" << endl;
    }
};

void demonstrateCircularReference() {
    cout << "=== 创建循环引用 ===" << endl;

    auto node1 = make_shared<BadNode>();
    auto node2 = make_shared<BadNode>();

    node1->next = node2;  // node1 -> node2
    node2->prev = node1;  // node2 -> node1

    cout << "node1引用计数: " << node1.use_count() << endl;  // 2
    cout << "node2引用计数: " << node2.use_count() << endl;  // 2

    cout << "=== 离开作用域 ===" << endl;
    // node1和node2销毁,但它们指向的对象不会被销毁!
    // 因为它们互相持有对方的shared_ptr
}
// 没有看到"BadNode析构"输出 - 内存泄漏!

int main() {
    demonstrateCircularReference();
    cout << "程序结束" << endl;
    return 0;
}

21.3.2 使用weak_ptr解决循环引用

#include <iostream>
#include <memory>
using namespace std;

// ✅ 解决:使用weak_ptr打破循环
class GoodNode {
public:
    shared_ptr<GoodNode> next;
    weak_ptr<GoodNode> prev;  // 使用weak_ptr

    ~GoodNode() {
        cout << "GoodNode析构" << endl;
    }
};

void demonstrateWeakPtrSolution() {
    cout << "=== 创建链表(使用weak_ptr) ===" << endl;

    auto node1 = make_shared<GoodNode>();
    auto node2 = make_shared<GoodNode>();

    node1->next = node2;  // shared_ptr
    node2->prev = node1;  // weak_ptr(不增加引用计数)

    cout << "node1引用计数: " << node1.use_count() << endl;  // 1
    cout << "node2引用计数: " << node2.use_count() << endl;  // 2

    // 使用prev指针
    if (auto prev = node2->prev.lock()) {
        cout << "node2的前驱存在" << endl;
    }

    cout << "=== 离开作用域 ===" << endl;
}
// 会看到两次"GoodNode析构" - 正确释放内存

int main() {
    demonstrateWeakPtrSolution();
    cout << "程序结束" << endl;
    return 0;
}

21.3.3 实际案例:树形结构

#include <iostream>
#include <memory>
#include <vector>
using namespace std;

class TreeNode : public enable_shared_from_this<TreeNode> {
private:
    int value;
    weak_ptr<TreeNode> parent;           // 使用weak_ptr避免循环引用
    vector<shared_ptr<TreeNode>> children;

public:
    TreeNode(int v) : value(v) {
        cout << "TreeNode(" << value << ") 构造" << endl;
    }

    ~TreeNode() {
        cout << "TreeNode(" << value << ") 析构" << endl;
    }

    void addChild(shared_ptr<TreeNode> child) {
        children.push_back(child);
        child->parent = shared_from_this();
    }

    shared_ptr<TreeNode> getParent() {
        return parent.lock();
    }

    void print(int level = 0) {
        cout << string(level * 2, ' ') << value << endl;
        for (auto& child : children) {
            child->print(level + 1);
        }
    }
};

void demonstrateTree() {
    cout << "=== 创建树 ===" << endl;

    auto root = make_shared<TreeNode>(1);
    auto child1 = make_shared<TreeNode>(2);
    auto child2 = make_shared<TreeNode>(3);
    auto grandchild = make_shared<TreeNode>(4);

    root->addChild(child1);
    root->addChild(child2);
    child1->addChild(grandchild);

    cout << "\n树结构:" << endl;
    root->print();

    cout << "\n检查parent指针:" << endl;
    if (auto parent = grandchild->getParent()) {
        cout << "grandchild的父节点存在" << endl;
    }

    cout << "\n=== 离开作用域 ===" << endl;
}

int main() {
    demonstrateTree();
    cout << "\n程序结束" << endl;
    return 0;
}

21.3.4 实际案例:观察者模式

#include <iostream>
#include <memory>
#include <vector>
#include <algorithm>
using namespace std;

class Observer {
public:
    virtual ~Observer() {
        cout << "Observer析构" << endl;
    }

    virtual void update(const string& message) = 0;
};

class ConcreteObserver : public Observer {
private:
    string name;

public:
    ConcreteObserver(const string& n) : name(n) {
        cout << "ConcreteObserver(" << name << ") 构造" << endl;
    }

    ~ConcreteObserver() {
        cout << "ConcreteObserver(" << name << ") 析构" << endl;
    }

    void update(const string& message) override {
        cout << name << " 收到消息: " << message << endl;
    }
};

class Subject {
private:
    vector<weak_ptr<Observer>> observers;  // 使用weak_ptr

public:
    void attach(shared_ptr<Observer> observer) {
        observers.push_back(observer);
        cout << "附加观察者" << endl;
    }

    void notify(const string& message) {
        cout << "\n通知所有观察者..." << endl;

        // 清理已失效的观察者
        observers.erase(
            remove_if(observers.begin(), observers.end(),
                     [](const weak_ptr<Observer>& wp) {
                         return wp.expired();
                     }),
            observers.end()
        );

        // 通知有效的观察者
        for (auto& weakObs : observers) {
            if (auto obs = weakObs.lock()) {
                obs->update(message);
            }
        }
    }
};

void demonstrateObserverPattern() {
    Subject subject;

    {
        auto obs1 = make_shared<ConcreteObserver>("观察者1");
        auto obs2 = make_shared<ConcreteObserver>("观察者2");

        subject.attach(obs1);
        subject.attach(obs2);

        subject.notify("第一次事件");

        cout << "\n=== obs2离开作用域 ===" << endl;
    }

    // obs2已销毁
    subject.notify("第二次事件");
}

int main() {
    demonstrateObserverPattern();
    return 0;
}

21.4 智能指针性能分析

21.4.1 内存开销对比

#include <iostream>
#include <memory>
using namespace std;

void demonstrateMemoryOverhead() {
    cout << "=== 内存开销对比 ===" << endl;

    // 裸指针
    int* rawPtr = new int(42);
    cout << "裸指针大小: " << sizeof(rawPtr) << " 字节" << endl;

    // unique_ptr
    unique_ptr<int> uniquePtr(new int(42));
    cout << "unique_ptr大小: " << sizeof(uniquePtr) << " 字节" << endl;

    // shared_ptr
    shared_ptr<int> sharedPtr = make_shared<int>(42);
    cout << "shared_ptr大小: " << sizeof(sharedPtr) << " 字节" << endl;

    // weak_ptr
    weak_ptr<int> weakPtr = sharedPtr;
    cout << "weak_ptr大小: " << sizeof(weakPtr) << " 字节" << endl;

    delete rawPtr;

    cout << "\n=== 控制块开销 ===" << endl;
    cout << "shared_ptr需要额外的控制块存储引用计数" << endl;
    cout << "make_shared可以减少一次内存分配" << endl;
}

int main() {
    demonstrateMemoryOverhead();
    return 0;
}

内存开销总结

  • 裸指针:8字节(64位系统)
  • unique_ptr:8字节(无额外开销)
  • shared_ptr:16字节(指针 + 控制块指针)
  • weak_ptr:16字节(与shared_ptr相同)
  • shared_ptr控制块:约24-32字节

21.4.2 性能测试

#include <iostream>
#include <memory>
#include <chrono>
#include <vector>
using namespace std;
using namespace chrono;

const int N = 1000000;

void benchmarkRawPointer() {
    auto start = high_resolution_clock::now();

    vector<int*> vec;
    for (int i = 0; i < N; ++i) {
        vec.push_back(new int(i));
    }

    for (auto ptr : vec) {
        (*ptr)++;
    }

    for (auto ptr : vec) {
        delete ptr;
    }

    auto end = high_resolution_clock::now();
    auto duration = duration_cast<milliseconds>(end - start);
    cout << "裸指针耗时: " << duration.count() << "ms" << endl;
}

void benchmarkUniquePtr() {
    auto start = high_resolution_clock::now();

    vector<unique_ptr<int>> vec;
    for (int i = 0; i < N; ++i) {
        vec.push_back(make_unique<int>(i));
    }

    for (auto& ptr : vec) {
        (*ptr)++;
    }

    // 自动释放

    auto end = high_resolution_clock::now();
    auto duration = duration_cast<milliseconds>(end - start);
    cout << "unique_ptr耗时: " << duration.count() << "ms" << endl;
}

void benchmarkSharedPtr() {
    auto start = high_resolution_clock::now();

    vector<shared_ptr<int>> vec;
    for (int i = 0; i < N; ++i) {
        vec.push_back(make_shared<int>(i));
    }

    for (auto& ptr : vec) {
        (*ptr)++;
    }

    // 自动释放

    auto end = high_resolution_clock::now();
    auto duration = duration_cast<milliseconds>(end - start);
    cout << "shared_ptr耗时: " << duration.count() << "ms" << endl;
}

void benchmarkSharedPtrCopy() {
    auto start = high_resolution_clock::now();

    vector<shared_ptr<int>> vec;
    for (int i = 0; i < N; ++i) {
        vec.push_back(make_shared<int>(i));
    }

    // 大量复制操作(引用计数增减)
    for (int i = 0; i < 100; ++i) {
        auto copy = vec;
    }

    auto end = high_resolution_clock::now();
    auto duration = duration_cast<milliseconds>(end - start);
    cout << "shared_ptr复制耗时: " << duration.count() << "ms" << endl;
}

int main() {
    benchmarkRawPointer();
    benchmarkUniquePtr();
    benchmarkSharedPtr();
    benchmarkSharedPtrCopy();

    return 0;
}

21.4.3 优化建议

#include <iostream>
#include <memory>
#include <vector>
using namespace std;

// ❌ 不好:频繁复制shared_ptr
void inefficientCode() {
    auto ptr = make_shared<int>(42);

    // 每次复制都会增减引用计数(原子操作,有开销)
    for (int i = 0; i < 1000; ++i) {
        auto copy = ptr;  // 引用计数+1
        // 使用copy
    }  // 引用计数-1
}

// ✅ 更好:使用引用
void efficientCode() {
    auto ptr = make_shared<int>(42);

    // 使用const引用,避免复制
    for (int i = 0; i < 1000; ++i) {
        const auto& ref = ptr;
        // 使用ref
    }
}

// ✅ 优化1:使用make_shared
void optimization1() {
    // ❌ 不好:两次内存分配
    shared_ptr<int> ptr1(new int(42));

    // ✅ 更好:一次内存分配
    auto ptr2 = make_shared<int>(42);
}

// ✅ 优化2:避免不必要的shared_ptr
class DataProcessor {
private:
    vector<shared_ptr<int>> data;

public:
    // ❌ 不好:返回shared_ptr,引用计数增减
    shared_ptr<int> getDataBad(size_t index) {
        return data[index];
    }

    // ✅ 更好:返回原始指针(如果不需要共享所有权)
    int* getDataGood(size_t index) {
        return data[index].get();
    }

    // ✅ 或返回引用
    const int& getDataRef(size_t index) const {
        return *data[index];
    }
};

// ✅ 优化3:使用unique_ptr替代shared_ptr
void optimization3() {
    // 如果不需要共享所有权,使用unique_ptr
    unique_ptr<int> ptr = make_unique<int>(42);

    // unique_ptr更轻量,没有引用计数开销
}

void demonstrateOptimizations() {
    cout << "性能优化建议:" << endl;
    cout << "1. 优先使用make_shared和make_unique" << endl;
    cout << "2. 传递时使用const引用避免复制" << endl;
    cout << "3. 不需要共享所有权时使用unique_ptr" << endl;
    cout << "4. 返回值考虑使用原始指针或引用" << endl;
    cout << "5. 避免循环引用,使用weak_ptr" << endl;
}

int main() {
    demonstrateOptimizations();
    return 0;
}

21.5 实战练习

练习1:实现对象池

#include <iostream>
#include <memory>
#include <vector>
#include <queue>
using namespace std;

template<typename T>
class ObjectPool {
private:
    queue<unique_ptr<T>> pool;
    size_t maxSize;

public:
    ObjectPool(size_t size) : maxSize(size) {}

    // 获取对象(使用自定义删除器归还到池中)
    shared_ptr<T> acquire() {
        if (pool.empty()) {
            // 池为空,创建新对象
            return shared_ptr<T>(new T(), [this](T* ptr) {
                this->release(unique_ptr<T>(ptr));
            });
        }

        // 从池中取出对象
        unique_ptr<T> obj = move(pool.front());
        pool.pop();

        return shared_ptr<T>(obj.release(), [this](T* ptr) {
            this->release(unique_ptr<T>(ptr));
        });
    }

    // 归还对象到池
    void release(unique_ptr<T> obj) {
        if (pool.size() < maxSize) {
            pool.push(move(obj));
        }
        // 超过最大大小,自动销毁
    }

    size_t size() const {
        return pool.size();
    }
};

class ExpensiveObject {
public:
    ExpensiveObject() {
        cout << "ExpensiveObject 构造" << endl;
    }

    ~ExpensiveObject() {
        cout << "ExpensiveObject 析构" << endl;
    }

    void use() {
        cout << "使用对象" << endl;
    }
};

int main() {
    ObjectPool<ExpensiveObject> pool(3);

    {
        auto obj1 = pool.acquire();
        obj1->use();

        auto obj2 = pool.acquire();
        obj2->use();

        cout << "\n对象离开作用域,归还到池中\n" << endl;
    }

    cout << "池中对象数量: " << pool.size() << endl;

    // 再次获取对象(复用)
    auto obj3 = pool.acquire();
    obj3->use();

    return 0;
}

练习2:实现延迟初始化

#include <iostream>
#include <memory>
using namespace std;

template<typename T>
class Lazy {
private:
    mutable unique_ptr<T> value;
    function<T()> initializer;

public:
    Lazy(function<T()> init) : initializer(init) {}

    const T& get() const {
        if (!value) {
            cout << "首次访问,初始化对象" << endl;
            value = make_unique<T>(initializer());
        }
        return *value;
    }

    bool isInitialized() const {
        return value != nullptr;
    }
};

class HeavyResource {
private:
    int data[1000];

public:
    HeavyResource() {
        cout << "HeavyResource 构造(开销大)" << endl;
        for (int i = 0; i < 1000; ++i) {
            data[i] = i;
        }
    }

    void use() {
        cout << "使用HeavyResource" << endl;
    }
};

int main() {
    cout << "创建Lazy对象..." << endl;

    Lazy<HeavyResource> lazyResource([]() {
        return HeavyResource();
    });

    cout << "Lazy对象已创建,但资源未初始化" << endl;
    cout << "是否已初始化: " << lazyResource.isInitialized() << endl;

    cout << "\n首次使用..." << endl;
    lazyResource.get().use();

    cout << "\n再次使用..." << endl;
    lazyResource.get().use();

    return 0;
}

练习3:实现智能指针转换

#include <iostream>
#include <memory>
using namespace std;

class Base {
public:
    virtual ~Base() {
        cout << "Base析构" << endl;
    }

    virtual void print() {
        cout << "Base" << endl;
    }
};

class Derived : public Base {
public:
    ~Derived() {
        cout << "Derived析构" << endl;
    }

    void print() override {
        cout << "Derived" << endl;
    }

    void derivedMethod() {
        cout << "Derived专有方法" << endl;
    }
};

void demonstrateSmartPointerCasts() {
    // static_pointer_cast
    {
        shared_ptr<Base> basePtr = make_shared<Derived>();

        // 向下转型
        shared_ptr<Derived> derivedPtr =
            static_pointer_cast<Derived>(basePtr);

        derivedPtr->derivedMethod();

        cout << "引用计数: " << basePtr.use_count() << endl;  // 2
    }

    // dynamic_pointer_cast
    {
        shared_ptr<Base> basePtr = make_shared<Derived>();

        // 安全的向下转型
        if (auto derivedPtr = dynamic_pointer_cast<Derived>(basePtr)) {
            cout << "转型成功" << endl;
            derivedPtr->derivedMethod();
        } else {
            cout << "转型失败" << endl;
        }
    }

    // const_pointer_cast
    {
        shared_ptr<const int> constPtr = make_shared<const int>(42);

        // 移除const
        shared_ptr<int> nonConstPtr = const_pointer_cast<int>(constPtr);
        *nonConstPtr = 100;
    }
}

int main() {
    demonstrateSmartPointerCasts();
    return 0;
}

练习4:实现引用计数调试工具

#include <iostream>
#include <memory>
#include <map>
using namespace std;

class RefCountTracker {
private:
    static map<void*, int> refCounts;

public:
    template<typename T>
    static shared_ptr<T> track(shared_ptr<T> ptr) {
        void* address = ptr.get();
        refCounts[address] = ptr.use_count();

        cout << "对象 " << address << " 引用计数: "
             << refCounts[address] << endl;

        return ptr;
    }

    static void printAll() {
        cout << "\n=== 所有对象引用计数 ===" << endl;
        for (const auto& pair : refCounts) {
            cout << "对象 " << pair.first << ": "
                 << pair.second << endl;
        }
    }
};

map<void*, int> RefCountTracker::refCounts;

int main() {
    auto ptr1 = RefCountTracker::track(make_shared<int>(42));
    auto ptr2 = ptr1;

    RefCountTracker::track(ptr1);

    auto ptr3 = RefCountTracker::track(make_shared<double>(3.14));

    RefCountTracker::printAll();

    return 0;
}

参考资料

  1. 书籍

    • Stanley B. Lippman. 《C++ Primer》(第5版) - 第12章 动态内存
    • Bjarne Stroustrup. 《C++程序设计语言》(第4版) - 资源管理
    • Scott Meyers. 《Effective Modern C++》 - 条款18-22 智能指针
    • Herb Sutter. 《Exceptional C++》 - 资源管理
  2. 在线文档

  3. 核心概念

  4. 技术文章

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐