当我将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
答案 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