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

实现类std::shared_ptr智能指针时如何禁止get()返回值赋值操作?

实现方案

你当前的代码已经满足了你列出的4条使用规则的核心约束:因为你已经给接收裸指针的构造函数加了explicit修饰,所以所有需要隐式调用构造函数的场景(shared_ptr<A> pA = new A、shared_ptr<A> pA2 = pA.get())都会被编译器直接拦截,只有直接构造、nullptr赋值、同类型智能指针拷贝/移动是允许的。
需要补充的修改点如下:

1. 调整Get方法返回值类型

首先引入<type_traits>头文件,将Get方法的返回值修改为std::remove_extent_t<T>*,对齐标准库行为,同时支持数组类型的智能指针:

#include <type_traits>

// 类内Get方法修改为:
std::remove_extent_t<T>* Get() noexcept { return m_pRes; }
const std::remove_extent_t<T>* Get() const noexcept { return m_pRes; }

std::remove_extent_t的作用是去掉类型的数组修饰,比如T是int[]的时候,返回值类型就是int*,和标准库shared_ptr的行为完全一致。

2. 补充实现MakeShared工具函数

和标准库std::make_shared对齐,避免用户手动调用new,降低使用风险:

template<typename T, typename... Args>
SharedPtr<T> MakeShared(Args&&... args)
{
    return SharedPtr<T>(new T(std::forward<Args>(args)...));
}

如果需要支持数组类型,可以单独偏特化该函数,内部使用new[]分配内存。

3. 可选优化点

  • 你当前的CastTo方法用了C风格强制转型,建议改为和assert判断对应的dynamic_cast,避免非法转型:
template<typename S>
SharedPtr<S> CastTo() const
{
    S* pCastRes = dynamic_cast<S*>(m_pRes);
    assert(pCastRes != nullptr && "[SharedPtr] Dynamic Cast Failed");

    SharedPtr<S> pCast;
    pCast.m_iRefCount = m_iRefCount;
    pCast.m_pRes = pCastRes;
    pCast.AddRef();

    return pCast;
}
  • 如果需要支持数组类型的智能指针,还需要对析构逻辑做偏特化,区分delete和delete[]调用,避免数组内存泄漏。
  • 可以给所有不会抛出异常的方法加上noexcept修饰,对齐标准库的异常规范。

内容的提问来源于stack exchange,提问作者Y.frank

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 12:48:02