当作为const引用传递给基类时,为什么shared_ptr计数器增加?

poo*_*a13 3 c++ polymorphism smart-pointers shared-ptr c++11

shared_ptr<drived>当我将计数器传递给需要a的函数时,为什么计数器会增加const shared_ptr<base>&

这个问题中,答案之一是:

shared_ptr<Base> and shared_ptr<Derived> are not covariant
Run Code Online (Sandbox Code Playgroud)

我怀疑这与我的问题有关。它们不是协变是什么意思?

这是一个代码片段,用于展示这种情况:

#include <iostream>
#include <memory>

class Base {};

class Derived : public Base {};

void f(const std::shared_ptr<Base>& x)
{
    std::cout << "in function expecting const shared_ptr<Base>& - Use count: " << x.use_count() << std::endl;
}

int main(int argc, char const *argv[])
{
    std::cout << "Base class" << std::endl;
    auto a = std::make_shared<Base>();
    std::cout << "Created shared_ptr:  Initial use count: " << a.use_count() << std::endl;
    f(a);

    std::cout << "------------------\nChild class" << std::endl;
    auto b = std::make_shared<Derived>();
    std::cout << "Created shared_ptr. Initial use count: " << b.use_count() << std::endl;
    f(b);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

结果是:

>> g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
Base class
Created shared_ptr:  Initial use count: 1
in function expecting const shared_ptr<Base>& - Use count: 1
------------------
Child class
Created shared_ptr. Initial use count: 1
in function expecting const shared_ptr<Base>& - Use count: 2
Run Code Online (Sandbox Code Playgroud)

Kev*_*vin 7

A shared_ptr<Derived>不是shared_ptr<Base>。它们是完全不同的类型。

为了从中获得一个shared_ptr<Base>shared_ptr<Derived>您需要创建一个。编译器可以调用构造函数,因为它没有标记为显式。这将增加使用次数,因为它们共享所有权。

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

构造一个shared_ptr,它共享由管理的对象的所有权r。如果不r管理对象,也*this就不管理对象。如果Y*不能从(直到C ++ 17)隐式转换为(直到C ++ 17)兼容,则模板重载不参与重载解析T*

您可以亲眼看到shared_ptr通过更改f()为非常量引用创建了新的引用。编译器应该给您一个错误,因为您不能将临时绑定到非常量引用。看这里