智能指针:线程安全与高效管理指南
智能指针的线程安全性
C++11的智能指针在多线程环境下的表现不同。shared_ptr的引用计数是线程安全的,但指向的对象本身不保证线程安全。若需多线程访问同一对象,需额外同步机制。unique_ptr因独占所有权,线程安全性依赖于对象的转移和释放逻辑。
std::shared_ptr<int> ptr = std::make_shared<int>(42);
// 引用计数操作安全,但修改 *ptr 需加锁
std::mutex mtx;
mtx.lock();
*ptr = 100;
mtx.unlock();
自定义删除器的应用
智能指针允许通过模板参数指定自定义删除器,适用于管理非传统资源(如文件句柄、网络连接)。shared_ptr和unique_ptr均支持此功能,但语法略有差异。
// unique_ptr 自定义删除器(函数对象)
struct FileDeleter {
void operator()(FILE* fp) const {
if (fp) fclose(fp);
}
};
std::unique_ptr<FILE, FileDeleter> filePtr(fopen("test.txt", "r"));
// shared_ptr 自定义删除器(Lambda表达式)
auto socketDeleter = [](Socket* s) { s->close(); delete s; };
std::shared_ptr<Socket> sockPtr(new Socket(), socketDeleter);
循环引用的解决方案
shared_ptr的循环引用会导致内存泄漏。例如,两个类互相持有对方的shared_ptr,引用计数无法归零。解决方法是使用weak_ptr打破循环,它不增加引用计数且需通过lock()获取临时shared_ptr访问资源。
class B;
class A {
public:
std::shared_ptr<B> bPtr;
~A() { std::cout << "A destroyed\n"; }
};
class B {
public:
std::weak_ptr<A> aWeakPtr; // 改用 weak_ptr
~B() { std::cout << "B destroyed\n"; }
};
// 使用示例
auto a = std::make_shared<A>();
auto b = std::make_shared<B>();
a->bPtr = b;
b->aWeakPtr = a; // 不会增加引用计数
性能优化与使用场景
make_shared的优势:合并引用计数与对象的内存分配,减少内存碎片,但对象生命周期可能与控制块绑定。unique_ptr的高效性:零开销抽象,适用于独占资源,如工厂模式返回的资源所有权转移。weak_ptr的延迟加载:适用于缓存、观察者模式,避免持有资源阻止其释放。
// make_shared 优化示例
auto ptr = std::make_shared<Resource>(args); // 单次分配
// unique_ptr 用于工厂模式
std::unique_ptr<Base> createObject(int type) {
return std::unique_ptr<Base>(new Derived(type));
}
与RAII原则的结合
智能指针是RAII(资源获取即初始化)的典型实现,确保资源在析构时自动释放。结合作用域规则,可避免手动delete导致的错误。例如,在异常发生时,局部智能指针仍能正确释放资源。
void process() {
auto res = std::make_shared<Resource>();
if (error_occurred) throw std::runtime_error("Error");
// res 会在栈展开时自动释放
}
兼容性与迁移建议
从传统指针迁移到智能指针时需注意:
- 避免混用
new/delete与智能指针。 - 使用
get()获取原始指针时需确保智能指针生命周期覆盖使用期。 - 优先选择
make_shared和make_unique(C++14引入)而非显式new。
// 迁移示例
// 旧代码
Resource* oldPtr = new Resource();
delete oldPtr;
// 新代码
auto newPtr = std::make_unique<Resource>();
BbS.okacop081.info/PoSt/1120_905200.HtM
BbS.okacop082.info/PoSt/1120_698137.HtM
BbS.okacop083.info/PoSt/1120_341766.HtM
BbS.okacop084.info/PoSt/1120_258828.HtM
BbS.okacop085.info/PoSt/1120_742719.HtM
BbS.okacop086.info/PoSt/1120_968786.HtM
BbS.okacop087.info/PoSt/1120_632996.HtM
BbS.okacop088.info/PoSt/1120_861215.HtM
BbS.okacop090.info/PoSt/1120_587072.HtM
BbS.okacop091.info/PoSt/1120_083503.HtM
BbS.okacop081.info/PoSt/1120_735510.HtM
BbS.okacop082.info/PoSt/1120_988084.HtM
BbS.okacop083.info/PoSt/1120_057453.HtM
BbS.okacop084.info/PoSt/1120_977131.HtM
BbS.okacop085.info/PoSt/1120_171267.HtM
BbS.okacop086.info/PoSt/1120_303669.HtM
BbS.okacop087.info/PoSt/1120_905452.HtM
BbS.okacop088.info/PoSt/1120_588341.HtM
BbS.okacop090.info/PoSt/1120_961108.HtM
BbS.okacop091.info/PoSt/1120_536224.HtM
BbS.okacop081.info/PoSt/1120_571090.HtM
BbS.okacop082.info/PoSt/1120_622847.HtM
BbS.okacop083.info/PoSt/1120_364573.HtM
BbS.okacop084.info/PoSt/1120_575281.HtM
BbS.okacop085.info/PoSt/1120_372466.HtM
BbS.okacop086.info/PoSt/1120_338916.HtM
BbS.okacop087.info/PoSt/1120_808743.HtM
BbS.okacop088.info/PoSt/1120_958357.HtM
BbS.okacop090.info/PoSt/1120_554785.HtM
BbS.okacop091.info/PoSt/1120_845568.HtM
BbS.okacop081.info/PoSt/1120_861416.HtM
BbS.okacop082.info/PoSt/1120_237528.HtM
BbS.okacop083.info/PoSt/1120_863459.HtM
BbS.okacop084.info/PoSt/1120_751391.HtM
BbS.okacop085.info/PoSt/1120_927606.HtM
BbS.okacop086.info/PoSt/1120_812187.HtM
BbS.okacop087.info/PoSt/1120_176186.HtM
BbS.okacop088.info/PoSt/1120_964668.HtM
BbS.okacop090.info/PoSt/1120_713548.HtM
BbS.okacop091.info/PoSt/1120_086931.HtM
BbS.okacop081.info/PoSt/1120_607189.HtM
BbS.okacop082.info/PoSt/1120_731775.HtM
BbS.okacop083.info/PoSt/1120_560626.HtM
BbS.okacop084.info/PoSt/1120_732882.HtM
BbS.okacop085.info/PoSt/1120_202017.HtM
BbS.okacop086.info/PoSt/1120_534498.HtM
BbS.okacop087.info/PoSt/1120_113235.HtM
BbS.okacop088.info/PoSt/1120_472830.HtM
BbS.okacop090.info/PoSt/1120_789849.HtM
BbS.okacop091.info/PoSt/1120_879602.HtM
BbS.okacop081.info/PoSt/1120_044481.HtM
BbS.okacop082.info/PoSt/1120_945180.HtM
BbS.okacop083.info/PoSt/1120_374975.HtM
BbS.okacop084.info/PoSt/1120_741582.HtM
BbS.okacop085.info/PoSt/1120_119593.HtM
BbS.okacop086.info/PoSt/1120_586984.HtM
BbS.okacop087.info/PoSt/1120_650288.HtM
BbS.okacop088.info/PoSt/1120_592663.HtM
BbS.okacop090.info/PoSt/1120_113331.HtM
BbS.okacop091.info/PoSt/1120_379701.HtM
BbS.okacop081.info/PoSt/1120_607465.HtM
BbS.okacop082.info/PoSt/1120_453424.HtM
BbS.okacop083.info/PoSt/1120_788186.HtM
BbS.okacop084.info/PoSt/1120_931376.HtM
BbS.okacop085.info/PoSt/1120_195458.HtM
BbS.okacop086.info/PoSt/1120_059228.HtM
BbS.okacop087.info/PoSt/1120_611193.HtM
BbS.okacop088.info/PoSt/1120_407841.HtM
BbS.okacop090.info/PoSt/1120_507935.HtM
BbS.okacop091.info/PoSt/1120_677509.HtM
BbS.okacop092.info/PoSt/1120_468434.HtM
BbS.okacop093.info/PoSt/1120_512870.HtM
BbS.okacop094.info/PoSt/1120_878685.HtM
BbS.okacop095.info/PoSt/1120_677466.HtM
BbS.okacop096.info/PoSt/1120_539307.HtM
BbS.okacop097.info/PoSt/1120_288262.HtM
BbS.okacop098.info/PoSt/1120_021384.HtM
BbS.okacop099.info/PoSt/1120_773018.HtM
BbS.okacop114.info/PoSt/1120_687411.HtM
BbS.okacop829.info/PoSt/1120_742828.HtM
