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

const std::shared_ptr引用向上转型的工作机制探究

关于std::shared_ptr向上转型的疑问

我发现当const std::shared_ptr&向上转型时,会创建一个指向同一转型后对象的基类新共享指针,示例代码如下:

#include <iostream>
#include <memory>

class Animal
{
};

class Cat : public Animal
{
};

void display(const std::shared_ptr<Animal>& animal)
{
    std::cout << animal.use_count() << std::endl;
}

int main()
{
    auto cat = std::make_shared<Cat>();

    std::cout << cat.use_count() << std::endl;
    display(cat);
    std::cout << cat.use_count() << std::endl;
}

运行这段代码的输出为:

sujith@AKLJoincggDLEd:~/sujith$ g++  -std=c++17 main.cpp
sujith@AKLJoincggDLEd:~/sujith$ ./a.out
1
2
1
sujith@AKLJoincggDLEd:~/sujith$

我的疑问是:

  • 这个行为是通过哪个运算符/构造函数实现的?
  • 其他引用类型的向上转型也能获得相同行为吗?
  • 还是说这是shared_ptr引用特有的处理方式?

解答

1. 实现机制

这个行为是通过std::shared_ptr的模板转换构造函数实现的。C++标准库为shared_ptr定义了如下模板构造函数:

template <class Y>
shared_ptr(const shared_ptr<Y>& r) noexcept;

当子类类型Y可以隐式向上转型为基类类型T(即Y*能转换为T*)时,这个构造函数会被触发:它会创建一个新的shared_ptr<T>实例,与原shared_ptr<Y>共享同一个控制块,因此引用计数会临时增加。

在你的代码中,调用display(cat)时,编译器会先构造一个临时的shared_ptr<Animal>,再将这个临时对象的引用绑定到函数的const std::shared_ptr<Animal>&参数上。函数执行完毕后,临时的shared_ptr<Animal>被销毁,引用计数随之下降,这就是输出出现1→2→1的原因。

2. 其他引用类型的向上转型行为

普通对象引用的向上转型不会有这种引用计数变化的行为。比如Cat&转Animal&,本质只是同一个对象的不同类型视角引用,不会创建任何新对象,也不存在引用计数的概念。这种涉及引用计数的临时对象创建行为,是智能指针这类需要管理对象生命周期的类型特有的。

3. 是否为shared_ptr引用特有

是的,这是shared_ptr(包括其引用形式)特有的处理方式。核心原因在于shared_ptr本身是一个管理原始指针的包装对象,而非原始指针或普通引用。当你传递shared_ptr<Cat>给期望const shared_ptr<Animal>&的函数时,编译器必须先构造一个兼容的shared_ptr<Animal>临时对象,才能完成参数绑定——这个临时对象的创建和销毁直接影响了引用计数。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 01:07:33