4

次のベクトルを検討してください。

std::vector<std::shared_ptr<X>> myVector;

そして、指定された要素をベクトルに追加する次の 2 つの関数:

void foo1(std::shared_ptr<X> x)
{
    myVector.push_back(x);
}

void foo2(const std::shared_ptr<X>& x)
{
    myVector.push_back(x);
}

私の理解では、両方の関数が ashared_ptrXベクターにプッシュするため、 の参照カウントがインクリメントされますX。最初の関数では、参照カウントがさらにインクリメントおよびデクリメントされますが、これは不要です。

私の理解は正しいですか?したがって、2番目のオプションが望ましいですか?

4

3 に答える 3

3

foo1パラメータ (共有ポインタ) を値で渡します。したがって、 のコピー コンストラクタが呼び出されます (つまり、 でローカル コピーのstd::shared_ptr<X>デストラクタが呼び出されると、ref カウンタが増加してから減少します)。}foo1

foo2参照によってパラメーター (つまり、共有ポインター) を渡しますconst。したがって、const元のオブジェクトの修飾されたエイリアスを渡します (つまり、ref カウンターは増加しません)。

これは、次の例でも確認できます。

struct X {};

void foo1(std::shared_ptr<X> x) { 
  std::cout << "count in foo1(): " << x.use_count() << std::endl;
}

void foo2(const std::shared_ptr<X>& x) {
  std::cout << "count in foo2(): " << x.use_count() << std::endl;
}

int main() {
  std::shared_ptr<X> x(new X);
  std::cout << "count in main(): " << x.use_count() << std::endl;
  foo1(x);
  foo2(x);
}

出力:

count in main(): 1
count in foo1(): 2
count in foo2(): 1

ご覧のとおりfoo1、異なる shared_ptr インスタンスの数は 2 です。これは、 でshared_ptr定義されたオリジナルmainと でのコピーですfoo1。一方、foo2参照カウンターは 1 のままです。

したがって、あなたの推論は正しいです。

于 2015-11-05T20:04:25.557 に答える