Consider following code:
#include <iostream>
#include <memory>
class Test
{
public:
Test(int t) : t(t) {}
int t;
};
void test(std::shared_ptr<Test> t)
{
std::cout << t.use_count() << std::endl;
}
int main()
{
auto t = std::make_shared<Test>(1);
test(std::move(t)); //(1)
test(std::make_shared<Test>(2)); //(2)
}
Questions:
t
in void test(std::shared_ptr<Test> t)
, then temporary is destroyed. Is that correct?There is a total of 3 std::shared_ptr<Test>
created in your example:
auto t = std::make_shared<Test>(1);
test(std::move(t));
- The receiving t
in test()
is move-constructed.
test(std::make_shared<Test>(2));
- The receiving t
is the one created by make_shared()
. It's the same object because of mandatory copy/move-elision since C++17.
Prior to C++17, you could in theory get as many as 5 instantiations - but since this kind of elision was allowed (but not mandatory) in the previous version, you'll most probably only get 3 in those versions too. When using one of those earlier versions you can turn off this optimization in some compilers (g++
/clang++
for example) with -fno-elide-constructors
. In C++17 and later, the elision is mandatory and can therefore not be turned off.
Here's a demo which doesn't use shared_ptr
but a test class called foo
so that that you can track each instantiation. Note how there is only one foo
with the value 2
, which corresponds to your test(std::make_shared<Test>(2));
call.