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

时间:2019-06-27 21:38:43

标签: c++ c++11 polymorphism shared-ptr smart-pointers

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

this question中,答案之一提到:

shared_ptr<Base> and shared_ptr<Derived> are not covariant

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

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

#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;
}

结果:

>> 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

1 个答案:

答案 0 :(得分:7)

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

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

  

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

     

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

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