第21章-智能指针与内存管理
本章深入介绍C++11智能指针技术,详细讲解unique_ptr、shared_ptr、weak_ptr三种智能指针的特点和使用场景,对比原始指针与智能指针的差异,讲解RAII资源管理原则,演示如何避免内存泄漏和循环引用问题,帮助读者编写更安全、更现代的C++内存管理代码。
·
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;
}
参考资料
-
书籍
- Stanley B. Lippman. 《C++ Primer》(第5版) - 第12章 动态内存
- Bjarne Stroustrup. 《C++程序设计语言》(第4版) - 资源管理
- Scott Meyers. 《Effective Modern C++》 - 条款18-22 智能指针
- Herb Sutter. 《Exceptional C++》 - 资源管理
-
在线文档
-
核心概念
-
技术文章
更多推荐

所有评论(0)