You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++使用PIMPL模式时如何避免shared_ptr的额外性能开销

解决方案

针对你提出的「支持不完整类型、规避std::shared_ptr原子引用计数开销、仅用标准库实现」的核心需求,优先推荐**自定义类型擦除删除器的std::unique_ptr**方案,完美适配PIMPL等常见场景,性能接近原生裸指针,远高于带原子开销的std::shared_ptr。


方案1:带类型擦除删除器的std::unique_ptr

你之前对std::unique_ptr动态删除器的认知存在偏差:只要在构造std::unique_ptr时目标类型是完整的,就可以将销毁逻辑预存在删除器中,实现对不完整类型的支持,示例实现如下,完全适配你给出的std::fstream测试场景:

头文件(仅声明不完整类型)

#include <memory>
#include <iosfwd>

// 对外暴露的类型,此时std::fstream为不完整类型
class FileHandler {
public:
    FileHandler();
    ~FileHandler();
    // 按需实现移动构造/赋值,默认禁用拷贝即可
    FileHandler(FileHandler&&) = default;
    FileHandler& operator=(FileHandler&&) = default;
private:
    // 用函数指针作为删除器实现类型擦除,不需要知道std::fstream的完整定义
    std::unique_ptr<std::fstream, void(*)(std::fstream*)> _file;
};

实现文件(类型完整时构造智能指针)

#include <fstream>

FileHandler::FileHandler() 
    // 此时std::fstream是完整类型,lambda内部已经明确知道如何销毁对象
    : _file(new std::fstream, [](std::fstream* ptr) { delete ptr; })
{}

FileHandler::~FileHandler() = default;

该方案的核心优势:

  • 无原子引用计数开销,仅多一次删除器的间接调用,性能损失可以忽略
  • 完美支持不完整类型,完全适配PIMPL场景
  • 支持move-only类型(比如std::fstream),弥补了std::any要求类型可拷贝的缺陷
  • 完全基于标准库原生组件,无第三方依赖

方案2:需要共享所有权的场景

当前C++标准库没有提供官方的非原子版本std::shared_ptr,如果你的场景确实需要共享所有权、且完全不需要线程安全,可以自行实现一个极简的非原子引用计数智能指针,代码量不到100行,性能远高于标准std::shared_ptr,可以完全替代boost的非原子shared_ptr方案。


内容的提问来源于stack exchange,提问作者NoSenseEtAl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 09:24:04