包含引用模板化类的基类指针的类的赋值运算符和复制构造函数

时间:2014-07-31 11:51:42

标签: c++ templates copy-constructor deep-copy assignment-operator

为长标题道歉。我正在尝试为我称之为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的{​​{1}}派生的类定义如下:

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并以某种方式通过深度复制对象来填充目标地图,但我的问题是我不知道如何确定{{1}的类型隐藏在每个std::map<std::string,FieldBase*>指针下方......

Field

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:3)

你应该看一下克隆模式。

http://en.wikipedia.org/wiki/Cloning_(programming)

你要做的是向FieldBase添加一个纯抽象成员函数,它在大多数派生类型(Field)中定义。

所以:

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()));
}

答案 1 :(得分:2)

要实现深层复制,您可以添加抽象函数virtual FieldBase * FieldBase::clone() = 0;

然后,实施FieldBase* Field<T>::clone()将返回new Field<T>(*this);

唯一剩下的就是遍历Store::m_data的每个条目并致电it->second->clone();