次のコード スニペットでは:
shared_ptr<int> p;
{
p = shared_ptr<int>(new int);
cout<<p.use_count()<<endl;
}
cout<<p.use_count()<<endl;
出力は
1 1
なぜ最初の出力が なのか理解できませ1
ん2
。
次のコード スニペットでは:
shared_ptr<int> p;
{
p = shared_ptr<int>(new int);
cout<<p.use_count()<<endl;
}
cout<<p.use_count()<<endl;
出力は
1 1
なぜ最初の出力が なのか理解できませ1
ん2
。
一時オブジェクトの有効期間は、最初のオブジェクトが 2 を返すのに十分な長さではありませんp.use_count()
。一時オブジェクトは最初に破棄され、それが所有していたすべてのものの所有権を放棄します。
さらに、temporary は右辺値であるためp
、への代入は move-assignment になります。つまり、とにかく use-count が 2 になることはありません (高品質の実装を前提としています)。所有権は一時的な から に単純に転送され、p
1 を超えることはありません。
#include <memory>
#include <iostream>
int
main(int argc, char** argv) {
std::shared_ptr<int> p(new int);
std::shared_ptr<int> p2(p);
std::cout << p.use_count() << std::endl;
return 0;
}
output: 2
説明/編集: ソースでは、最初の 'p' は何の所有権も保持していません。p への 2 番目の参照では、一時的に割り当て、基本的に「p」の所有権を放棄しています。同様に、ほとんどの場合、この代入を満たすために move コンストラクターが使用されます。
編集:これはおそらくあなたが目指していたものでしたか?
#include <memory>
#include <iostream>
int
main(int argc, char** argv) {
std::shared_ptr<int> p(new int);
{
std::shared_ptr<int> p2(p);
std::cout << p.use_count() << std::endl;
}
std::cout << p.use_count() << std::endl;
return 0;
}
output: 2
1
boost.org から:
template<class Y> explicit shared_ptr(Y * p);
Requirements: p must be convertible to T *. Y must be a complete type. The expression delete p must be well-formed, must not invoke undefined behavior, and must not throw exceptions.
Effects: Constructs a shared_ptr that owns the pointer p.
Postconditions: use_count() == 1 && get() == p.
Throws: std::bad_alloc, or an implementation-defined exception when a resource other than memory could not be obtained.
Exception safety: If an exception is thrown, delete p is called.
Notes: p must be a pointer to an object that was allocated via a C++ new expression or be 0. The postcondition that use count is 1 holds even if p is 0; invoking delete on a pointer that has a value of 0 is harmless.
ご覧のとおり、新しい int から新しい shared_ptr を構築すると、最後の構造が解放されます。