cplusplus.com shared_ptr
page は、emptystd::shared_ptr
とnullshared_ptr
。 cppreference.com page は明確に区別を呼び出しませんが、std::shared_ptr
動作の説明で「空」とnullptr
との比較の両方を使用します。
空のshared_ptr
とnullの違いはありますか?そのような混合動作のポインターの使用例はありますか?空でないnull shared_ptr
は理にかなっていますか?通常の使用法(つまり、明示的に構築しなかった場合)で、空であるがnullではないshared_ptr
になる場合がありますか?
また、C++ 11バージョンの代わりにBoostバージョンを使用している場合、これらの回答のいずれかが変わりますか?
shared_ptr
の動作の奇妙なコーナーです。これには、owns何かとpoints to何か他のものを作成するshared_ptr
を作成できるコンストラクターがあります。
template< class Y >
shared_ptr( const shared_ptr<Y>& r, T *ptr );
このコンストラクタを使用して構築されたshared_ptr
所有権を共有とr
が、ポイントptr
が指すもの(つまり、get()
またはoperator->()
はptr
)を返します。これは、ptr
が所有するオブジェクトのサブオブジェクト(データメンバーなど)をr
が指す場合に便利です。
リンクしたページは、何も所有していないshared_ptr
を呼び出しますempty、および何も指定していないshared_ptr
(つまり、そのget() == nullptr
)nullを呼び出します。 (空はこの意味で標準で使用されます; nullはそうではありません。)null-but-not-empty shared_ptr
を構築できますが、そうではありません非常に便利。空ではないがnullではないshared_ptr
は本質的に非所有ポインターであり、これを使用して スタックに割り当てられた何かへのポインターをshared_ptr
を予期する関数に渡す (ただし、最初にAPI内にshared_ptr
を入れた人は誰でもパンチすることをお勧めします)。
boost::shared_ptr
も このコンストラクターを持っています 、エイリアスコンストラクターと呼びます。
空とnullのshared_ptrに違いはありますか?
空のshared_ptr
には制御ブロックがなく、その使用カウントは0と見なされます。空のshared_ptr
のコピーは別の空のshared_ptr
です。どちらも別個のshared_ptr
であり、共通の制御ブロックを持たないため、共通の制御ブロックを共有しません。空のshared_ptr
は、デフォルトのコンストラクターまたはnullptr
をとるコンストラクターで構築できます。
空でないnull shared_ptr
には、他のshared_ptr
sと共有できる制御ブロックがあります。空でないヌルのコピーshared_ptr
は、元のshared_ptr
と同じ制御ブロックを共有するshared_ptr
であるため、使用回数は0ではありません。shared_ptr
のすべてのコピーが同じnullptr
を共有すること。空でないnull shared_ptr
は、オブジェクトの型のnullptr
ではないnullポインタで構築できます
以下に例を示します。
#include <iostream>
#include <memory>
int main()
{
std::cout << "std::shared_ptr<int> ptr1:" << std::endl;
{
std::shared_ptr<int> ptr1;
std::cout << "\tuse count before copying ptr: " << ptr1.use_count() << std::endl;
std::shared_ptr<int> ptr2 = ptr1;
std::cout << "\tuse count after copying ptr: " << ptr1.use_count() << std::endl;
std::cout << "\tptr1 is " << (ptr1 ? "not null" : "null") << std::endl;
}
std::cout << std::endl;
std::cout << "std::shared_ptr<int> ptr1(nullptr):" << std::endl;
{
std::shared_ptr<int> ptr1(nullptr);
std::cout << "\tuse count before copying ptr: " << ptr1.use_count() << std::endl;
std::shared_ptr<int> ptr2 = ptr1;
std::cout << "\tuse count after copying ptr: " << ptr1.use_count() << std::endl;
std::cout << "\tptr1 is " << (ptr1 ? "not null" : "null") << std::endl;
}
std::cout << std::endl;
std::cout << "std::shared_ptr<int> ptr1(static_cast<int*>(nullptr))" << std::endl;
{
std::shared_ptr<int> ptr1(static_cast<int*>(nullptr));
std::cout << "\tuse count before copying ptr: " << ptr1.use_count() << std::endl;
std::shared_ptr<int> ptr2 = ptr1;
std::cout << "\tuse count after copying ptr: " << ptr1.use_count() << std::endl;
std::cout << "\tptr1 is " << (ptr1 ? "not null" : "null") << std::endl;
}
std::cout << std::endl;
return 0;
}
以下を出力します:
std::shared_ptr<int> ptr1:
use count before copying ptr: 0
use count after copying ptr: 0
ptr1 is null
std::shared_ptr<int> ptr1(nullptr):
use count before copying ptr: 0
use count after copying ptr: 0
ptr1 is null
std::shared_ptr<int> ptr1(static_cast<int*>(nullptr))
use count before copying ptr: 1
use count after copying ptr: 2
ptr1 is null