5

コンテナーNodeを使用してバイナリ ツリーを実装するためにカスタム クラスを作成しています。マップのキーはオブジェクトの識別子です。クラスでは、コピー コンストラクターを実装する必要がありました。map<int,Node>intNodeNode

マップにオブジェクトを挿入すると、 のコピー コンストラクターが2 回呼び出されるNodeことに気付きました。Nodeなんで?

cout << "node2" << endl;
Node node2;
node2.set_depth(2);
node2.make_it_branch(3,4);

cout << "map" << endl;
map<int,Node> mapping;
cout << "toInsert" << endl;
pair<int,Node> toInsert = pair<int,Node>(2,node2);
cout << "insert" << endl;
mapping.insert(toInsert);

上記のコードを実行すると、出力は次のようになります。

node2
--- Node()
map
toInsert
--- Node(const Node& orig)
insert
--- Node(const Node& orig)   // Why does the copy constructor be invoked twice?
--- Node(const Node& orig)   // ------------------------------------------------
--- ~Node()
--- ~Node()
--- ~Node()
--- ~Node()
4

3 に答える 3

14

ほとんどの場合、マップの値型は:pair<int const, Node>ではなくpair<int, Node>、マップでは、キーは定数です。

aをinsert()受け入れ、を指定すると、変換を実行するために一時的なものを作成する必要があります。この一時的なものから、マップ内の値をコピーして作成できます。pair<int const, Node> const&pair<int, Node>

確認するには、次の行を変更します。

pair<int, Node> toInsert = pair<int, Node>(2, node2);

この行に:

pair<int const, Node> toInsert = pair<int const, Node>(2, node2);

そして、コピーコンストラクターへの余分な呼び出しが消えるのを見るはずです。

また、特定の数のコピーを実行するために標準ライブラリコンテナの具体的な実装は必要ないことにも注意してください。実装は異なる場合があり、最適化レベルが異なると状況も異なる可能性があります。

于 2013-03-06T12:25:18.030 に答える
1

を使用してpair<int,Node>います。insert メソッドが取る型は、map<K,V>::value_typeとして定義されていpair<const K,V>ます。コンパイラは、これら 2 つの型の間で変換するために、追加のコピーを挿入する必要があります。

map<int,Node>::value_typeの代わりに使ってみてくださいpair<int,Node>。ゼロから再作成するよりも、クラス自体で定義された型を使用することをお勧めします。

書くことで最初のコピーを避けることもできます。

map<int,Node>::value_type toInsert(2,node2);

それ以外の

map<int,Node>::value_type toInsert = map<int,Node>::value_type(2,node2);
于 2014-04-30T07:29:47.980 に答える
-1

次の場合:

toInsert = pair<int, Node>(2, node2);

node2をオブジェクトのコンストラクターに渡していpairます。参照渡しを行っていても、概念的にはを結合しているため、pairオブジェクトがオブジェクトのコピーを作成していることになりnode2ます。#1をコピーします。

このpairオブジェクトを挿入関数に渡すと、次のようになります。

mapping.insert(toInsert);

.. はい、参照渡ししていますが、コンテナは参照されているオブジェクトの有効期間について何も知りません ( toInsert)。したがって、コンテナに格納するための独自のコピーが作成されます。#2 をコピーします。

于 2013-03-06T12:35:25.367 に答える