包含指向派生模板类的基类指针的类的赋值运算符和复制构造函数
Posted
技术标签:
【中文标题】包含指向派生模板类的基类指针的类的赋值运算符和复制构造函数【英文标题】:Assignment operator and copy constructor for class containing base class pointer to derived templated class 【发布时间】:2014-09-23 08:35:40 【问题描述】:为长标题道歉。我正在尝试为我称为Store
的类编写赋值运算符和复制构造函数。
Store
的用途是保存由std::string
标识的其他结构(例如整数、浮点数),可以从Store
添加/检索。这是通过std::map
实现的,std::string
作为映射中的“键”,特定结构作为映射中的“值”。
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;
;
其中FieldBase
定义如下:
class FieldBase
public:
FieldBase()
virtual ~FieldBase()
从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;
;
Store
中的添加和检索功能定义如下。
要检索,请使用 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();
再补充一句,使用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;
所以,在描述了类及其交互之后,我终于得出了这个问题:
复制构造函数和赋值运算符应该如何查找Store
?
显然,应该遍历std::map<std::string,FieldBase*>
并以某种方式通过深度复制对象来填充目标地图,但我的问题是我不知道如何确定隐藏在每个@ 下方的Field
的类型987654343@指针...
// How should these be implemented ???
Store::Store(const Store& other);
Store& Store::operator=(const Store& other);
非常感谢任何帮助。
【问题讨论】:
链接到cloning objects in C++ 【参考方案1】:要实现深拷贝,可以添加抽象函数virtual FieldBase * FieldBase::clone() = 0
;
实现FieldBase* Field<T>::clone()
然后将返回new Field<T>(*this)
;
唯一剩下的就是遍历Store::m_data
的每个条目并调用it->second->clone()
;
【讨论】:
【参考方案2】:你应该看看克隆模式。
http://en.wikipedia.org/wiki/Cloning_(programming)
您所做的是向 FieldBase 添加一个纯抽象成员函数,该函数在最派生类型(字段)中定义。
所以:
virtual FieldBase* clone() const = 0; //! This goes in FieldBase
FieldBase* clone() const return new Field<T>(m_value); //! This goes in Field
然后在复制构造函数中迭代映射并克隆底层值,然后将它们插入新实例的映射中。
类似这样的:
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()));
【讨论】:
以上是关于包含指向派生模板类的基类指针的类的赋值运算符和复制构造函数的主要内容,如果未能解决你的问题,请参考以下文章