STDの浅い/深いコピー::マップ
-
20-09-2019 - |
質問
私は最善これらをどのように実装するのでしょうか?私はこのような何かを考えます:
using namespace std;
shape_container
shape_container::clone_deep () const
{
shape_container* ptr = new shape_container();
copy( data.begin(), data.end(), (*ptr).begin() );
return *ptr;
}
shape_container
shape_container::clone_shallow () const
{
return *( new shape_container(*this) );
}
次のようにメンバーdata
が定義されている
std::map<std::string, shape*> data;
これは、残念ながら、動作しません。ここでは、コンパイラエラーがだ、私は本当にそれを理解していない。
g++ -Wall -O2 -pedantic -I../../UnitTest++/src/ -I./libfglwin/include/ -I. -c shape_container.cpp -o shape_container.o
/usr/include/c++/4.2.1/bits/stl_pair.h: In member function ‘std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, shape*>& std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, shape*>::operator=(const std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, shape*>&)’:
/usr/include/c++/4.2.1/bits/stl_pair.h:69: instantiated from ‘static _OI std::__copy<<anonymous>, <template-parameter-1-2> >::copy(_II, _II, _OI) [with _II = std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, shape*> >, _OI = std::_Rb_tree_iterator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, shape*> >, bool <anonymous> = false, <template-parameter-1-2> = std::bidirectional_iterator_tag]’
/usr/include/c++/4.2.1/bits/stl_algobase.h:315: instantiated from ‘_OI std::__copy_aux(_II, _II, _OI) [with _II = std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, shape*> >, _OI = std::_Rb_tree_iterator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, shape*> >]’
/usr/include/c++/4.2.1/bits/stl_algobase.h:340: instantiated from ‘static _OI std::__copy_normal<<anonymous>, <anonymous> >::__copy_n(_II, _II, _OI) [with _II = std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, shape*> >, _OI = std::_Rb_tree_iterator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, shape*> >, bool <anonymous> = false, bool <anonymous> = false]’
/usr/include/c++/4.2.1/bits/stl_algobase.h:401: instantiated from ‘_OutputIterator std::copy(_InputIterator, _InputIterator, _OutputIterator) [with _InputIterator = std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, shape*> >, _OutputIterator = std::_Rb_tree_iterator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, shape*> >]’
shape_container.cpp:70: instantiated from here
/usr/include/c++/4.2.1/bits/stl_pair.h:69: error: non-static const member ‘const std::basic_string<char, std::char_traits<char>, std::allocator<char> > std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, shape*>::first’, can't use default assignment operator
/usr/include/c++/4.2.1/bits/stl_algobase.h: In static member function ‘static _OI std::__copy<<anonymous>, <template-parameter-1-2> >::copy(_II, _II, _OI) [with _II = std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, shape*> >, _OI = std::_Rb_tree_iterator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, shape*> >, bool <anonymous> = false, <template-parameter-1-2> = std::bidirectional_iterator_tag]’:
/usr/include/c++/4.2.1/bits/stl_algobase.h:268: note: synthesized method ‘std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, shape*>& std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, shape*>::operator=(const std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, shape*>&)’ first required here
どういうわけか、これは私には不必要に複雑に見えます。即ち 真と私はそれを改善することができますか?
ところで、私持っているクローン()メソッド クラスで私は形から派生しました。おそらく、私はそれらを使用することができます clone_deep方法について?彼らは大丈夫か?彼らは何かを見て このような:
class shape
{
public:
/* Many methods. */
virtual shape* clone () const = 0;
protected:
colorRGB color_;
std::string name_;
};
class triangle2d : public shape
{
public:
/* Many methods. */
triangle2d* clone() const;
private:
point3d a_, b_, c_;
};
triangle2d*
triangle2d::clone() const
{
return new triangle2d(*this);
}
解決
通常のクローン機能は、新しいインスタンスへのポインタを返します。あなたが戻ってきていることはそれから漏洩して動的に割り当てられたisntanceから構築されたコピーである値によってオブジェクトです。
あなたが値で返すようにしたい場合は、あなたはnew
を使用しないでください。
例えばます。
shape_container shape_container::clone_shallow () const
{
return *this;
}
data
メンバーがちょうどstd::map
インスタンスである場合には、深いクローン場合にstd::copy
を行う必要はありませんので、それはどのような場合には、あなたの浅いクローンの一部としてコピーされます。、別の何かをやろうとしていません。
あなたがマップのstd::copy
をやってみたかった場合は、std::insert_iterator
を使用する必要があります。
私は事実後の各形状のclone
を行うことが容易であるかもしれないと思います。
例えばます。
shape_container shape_container::clone_deep() const
{
shape_container ret(*this);
for (std::map<std::string, shape*>::iterator i = ret.data.begin(); i != ret.data.end(); ++i)
{
i->second = i->second->clone();
}
return ret;
}
他のヒント
new
をshape_container
が、その後それは、戻り値を介してコピーされますので、すべてのあなたの例のまず、メモリリークが発生します。あなたはshape
例のように、ポインタを返す必要があります。
コンパイラのエラーは、それはあなたのための代入演算子を生成できない文句ですので、コピーに何らかの形で関係していると見えます。ここでも、ポインタを使って試してみて、その問題を離れて行く必要があります。
あなたは新しいにディープコピーを持つすべての要素にマップを作成しています。
のを参照カウントアプローチについて考え、それがより良いアプローチとなります。
1つのオプションは、深いを行い種類であなたの形状の種類をラップすることです オブジェクトのコピー:
class shape_deep_copy_wrapper {
// ...
public:
shape_deep_copy_wrapper (shape * shape)
: m_my_shape (shape)
{
}
shape_deep_copy_wrapper (shape_deep_copy_wrapper const & rhs)
: m_my_shape (rhs.m_my_shape.deep_copy ())
{
}
// ...
private:
shape * m_my_shape;
};
次に、このタイプのマップを構築します:
typedef std :: map < shape_deep_copy_wrapper , ... > DeepCopy ;
typedef std :: map < shape* , ... > ShallowCopy ;