为什么 shared_ptr 计数器在作为 const 引用传递给基 class 时递增?
Why is shared_ptr counter incremented when passed as const reference to base class?
为什么当我将它传递给需要 const shared_ptr<base>&
的函数时,shared_ptr<drived>
计数器递增?
在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
shared_ptr<Derived>
不是 shared_ptr<Base>
。他们是完全不同的类型。
为了从 shared_ptr<Derived>
中获得 shared_ptr<Base>
,您需要创建一个。编译器可以调用 constructor 因为它没有被显式标记。这将增加使用次数,因为他们共享所有权。
template< class Y > shared_ptr( const shared_ptr<Y>& r ) noexcept;
Constructs a shared_ptr which shares ownership of the object managed by r
. If r
manages no object, *this
manages no object too. The template overload doesn't participate in overload resolution if Y*
is not implicitly convertible to (until C++17) compatible with (since C++17) T*
.
您可以自己看到,通过将 f()
更改为采用 non-const 引用,创建了一个新的 shared_ptr
。编译器应该给你一个错误,因为你不能将临时绑定到 non-const 引用。 See here
为什么当我将它传递给需要 const shared_ptr<base>&
的函数时,shared_ptr<drived>
计数器递增?
在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
shared_ptr<Derived>
不是 shared_ptr<Base>
。他们是完全不同的类型。
为了从 shared_ptr<Derived>
中获得 shared_ptr<Base>
,您需要创建一个。编译器可以调用 constructor 因为它没有被显式标记。这将增加使用次数,因为他们共享所有权。
template< class Y > shared_ptr( const shared_ptr<Y>& r ) noexcept;
Constructs a shared_ptr which shares ownership of the object managed by
r
. Ifr
manages no object,*this
manages no object too. The template overload doesn't participate in overload resolution ifY*
is not implicitly convertible to (until C++17) compatible with (since C++17)T*
.
您可以自己看到,通过将 f()
更改为采用 non-const 引用,创建了一个新的 shared_ptr
。编译器应该给你一个错误,因为你不能将临时绑定到 non-const 引用。 See here