[英]Assignment operator and copy constructor for class containing base class pointer to derived templated class
Apologies for the long title. 对长标题表示歉意。 I am trying to write an assignment operator and a copy constructor for a class which I call
Store
. 我试图为我称为
Store
的类编写一个赋值运算符和一个复制构造函数。
The purpose of Store
is hold other structures (eg integers, floats), identified by a std::string
, which can be added/retrieved from the Store
. Store
的目的是保存其他结构(例如,整数,浮点数),这些结构由std::string
标识,可以从Store
添加/检索。 This is implemented with a std::map
, with a std::string
as the 'key' in the map and the particular structure as the 'value' in the map. 这是通过
std::map
,其中std::string
作为映射中的“键”,特定结构作为映射中的“值”。
Store
is defined as follows: Store
定义如下:
class Store {
public:
Store() {}
template <class T>
const T& get(const std::string& key) const;
template <class T>
void put(const std::string& key, const T& value, const bool& overwrite = false);
private:
std::map<std::string,FieldBase*> m_data;
};
where FieldBase
is defined as follows: 其中
FieldBase
的定义如下:
class FieldBase {
public:
FieldBase() {}
virtual ~FieldBase() {}
}
and a class derived from FieldBase
called Field
is defined as follows: 从
FieldBase
派生的称为Field
的类定义如下:
template <class T>
class Field : public FieldBase {
public:
Field(const T& value) : m_value(value) {}
template <class U>
Field(const Field<U>& other) : m_value( U(other.m_value) ) {}
template <class U>
Field& operator=(const Field<U>& other)
{
m_value = U(other.m_value);
return *this;
}
virtual ~Field() {}
const T& get() const { return m_value ; }
private:
T m_value;
};
The functionality in Store
to add and retrieve, is defined below. 下面定义了
Store
中添加和检索的功能。 To retrieve, one uses Store::get()
: 要进行检索,可以使用
Store::get()
:
template <class T>
const T& Store::get(const std::string& key) const
{
std::map<std::string,FieldBase*>::const_iterator it = m_data.find(key);
if ( it == m_data.end() ) {
std::cout << "Field with name " << key <<" doesn't exist!" << std::endl;
throw 0;
}
Field<T>* field = dynamic_cast<Field<T>*>(it->second);
if ( field == 0 ) {
std::cout << "Field with name " << key << " doesn't have correct type!" << std::endl;
throw 0;
}
return field->get();
}
and to add, one uses Store::put()
并添加一个使用
Store::put()
template <class T>
void Store::put(const std::string& key, const T& value, const bool& overwrite)
{
std::map<std::string,FieldBase*>::iterator it = m_data.find(key);
if ( it != m_data.end() ) {
if ( ! overwrite ) {
std::cout << "Field with name " << key << " doesn't exist!" << std::endl;
throw 0;
}
else {
delete it->second;
it->second = 0;
}
}
Field<T>* field = new Field<T>(value);
m_data[key] = field;
}
So, having described the classes and their interactions, I finally arrive at the question: 因此,在描述了类及其相互作用之后,我终于得出了一个问题:
How should the copy constructor and assignment operator look for Store
? 复制构造函数和赋值运算符应如何查找
Store
?
Obviously, one should iterate over the std::map<std::string,FieldBase*>
and somehow fill the target map by deep copying the objects, but my problem is that I don't know how to determine the type of the Field
which hides beneath each FieldBase
pointer... 显然,应该遍历
std::map<std::string,FieldBase*>
并通过深度复制对象以某种方式填充目标地图,但是我的问题是我不知道如何确定Field
的类型隐藏在每个FieldBase
指针下面...
// How should these be implemented ???
Store::Store(const Store& other);
Store& Store::operator=(const Store& other);
Any help is much appreciated. 任何帮助深表感谢。
You should look at the clone pattern. 您应该查看克隆模式。
http://en.wikipedia.org/wiki/Cloning_(programming) http://en.wikipedia.org/wiki/Cloning_(programming)
What you do is add a pure abstract member function to FieldBase which is defined in the most derived types (Field). 您要做的是将纯抽象成员函数添加到FieldBase中,该函数在大多数派生类型(字段)中定义。
So: 所以:
virtual FieldBase* clone() const = 0; //! This goes in FieldBase
FieldBase* clone() const { return new Field<T>(m_value); } //! This goes in Field
Then in the copy constructor you iterate over the map and clone the underlying values before inserting them in the new instance's map. 然后,在复制构造函数中,您遍历映射并克隆基础值,然后再将其插入新实例的映射中。
Something like this: 像这样:
Store(const Store& other)
{
typedef std::map<std::string, FieldBase*> StoreMap;
for (StoreMap::const_iterator it(other.m_data.begin()); it != other.m_data.end(); ++it)
m_data.insert(std::make_pair(it->first, it->second->clone()));
}
To implement a deep copy you can add an abstract function virtual FieldBase * FieldBase::clone() = 0
; 要实现深层副本,您可以添加抽象函数
virtual FieldBase * FieldBase::clone() = 0
;
The implementation FieldBase* Field<T>::clone()
would then return new Field<T>(*this)
; 然后,实现
FieldBase* Field<T>::clone()
将返回new Field<T>(*this)
;
The only thing left is to iterate over each entry of Store::m_data
and call it->second->clone()
; 剩下的唯一事情是遍历
Store::m_data
每个条目并调用it->second->clone()
;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.