4

解決できないと思われる別の問題があります...またはこのサイトで見つけます...

次のように宣言されたマップを持つオブジェクト(DataObjectと呼ばれる)があります。

std::map<size_t, DataElement*> dataElements;

これで、コピー関数(コピーコンストラクターで使用)ができました。

void DataObject::copy(DataObject const &other) {

    //here some code to clean up the old data in this object...

    //copy all the elements:
    size = other.getSize();
    for(size_t i = 0; i < size; ++i) {
            DataElement* dat = new DataElement(*other.dataElements[i]);
            dataElements[i] = dat;
    }

}

constオブジェクトではdataElements[i]を使用できないため、これはコンパイルされません。constオブジェクトが所有するマップ内のすべての要素のディープコピーを作成するにはどうすればよいですか?

find()関数がconstマップで可能であることは知っていますが、コピーしたい実際のオブジェクトに到達するにはどうすればよいですか?

4

6 に答える 6

9
std::map<size_t, DataElement*>::const_iterator it = other.dataElements.begin();
while(it != other.dataElements.end())
{
    dataElements[it->first] = new DataElement(*(it->second));
    ++it;
}

私はこれがうまくいくはずだとほぼ確信しています。

于 2010-10-27T15:39:11.007 に答える
1

std::transformを使用する必要があります。これにより、各要素で機能を実行しながらコピーが実行されます。あなたの場合、値の深いコピー。

したがって、これはトランスフォーマーとして機能します。

class DeepCopyMapPointer
{
   typedef std::map<size_t, DataElement*> map_type;
   typedef map_type::value_type value_type;

public:
   value_type operator()( const value_type & other ) const
   {
      return value_type(other.first, new DataElement(*other.second) );
   }
};

void DataObject::copy(DataObject const &other) 
{
   std::transform(other.dataElements.begin(), other.dataElements.end(),
      std::inserter( dataElements, dataElements.end() ), DeepCopyMapPointer() );
}

要素を複製して挿入が失敗するとリークが発生するため、それほど単純ではありません。std :: inserterの代わりに独自のインサーターを作成することでそれを回避できます...少しトリッキーですが、それが次の演習です。

于 2010-10-27T15:50:04.330 に答える
1

マップにはから0までの整数キーがあるためn - 1、コンテナタイプをベクトルに変更するだけで、現在のコードが適切に機能するはずです(十分なスペースがあることを確認するために、宛先コンテナのサイズを変更する必要があります)。

何らかの理由で使用する必要がある場合map(既存のAPI?)、発見したようoperator[]に、非定数バージョンしかありません。

代わりに、const_iteratorアプローチを使用してください(@PigBenの回答から賛成および引用):

std::map<size_t, DataElement*>::const_iterator it = other.dataElements.begin();
while(it != other.dataElements.end())
{
    dataElements[it->first] = new DataElement(*(it->second));
    ++it;
}
于 2010-10-27T17:10:31.467 に答える
0

今は答える時間があまりないので、簡単に説明します。マップ用のコピーコンストラクターがありますが、ディープコピーは実行されません。イテレータ(map.begin()、map.end())を使用します。* Iterはペアオブジェクトを提供するので、(* iter).firstおよび/または(* iter).secondを実行できます。(またはそのようなもの...久しぶりです...)

参照:http ://www.sgi.com/tech/stl/Map.html

于 2010-10-27T15:38:18.687 に答える
0
for (auto& kv : other.dataElements) {
            dataElements[kv.first] = new DataElement(*kv.second);
        }
于 2019-02-05T13:49:42.460 に答える
-1

たった1つの観察:-dataElementsへの直接アクセスを許可しています。(other.dataElements)。dataElementsをプライベートに保ち、GetDataElementのようなメソッドを与えます。

于 2010-10-27T15:41:40.500 に答える