父/子类的C ++拷贝构造函数问题

时间:2014-12-05 23:29:20

标签: c++ pointers constructor

我遇到了复制构造函数的问题......我假设有一个基本的答案,我错过了一些明显的东西 - 也许我做错了什么 - 但我我们无法弄明白。

基本上,我有一个父类和子类。父类包含指向(不同的)基类对象的指针向量。子类想要存储指向从该基础对象派生的对象的指针。

这是一个伪代码样本,如果有帮助的话:

// Base classes
class ItemRev {
  ...
}

class Item {

protected:

vector<ItemRev *> m_revPtrVec;

}


Item::Item(const Item &inputItemObj)
{
  // Copy contents of the input object's item rev pointer vector
  vector<ItemRev *>::const_iterator vecIter = (inputItemObj.m_revPtrVec).begin();
  while (vecIter != (inputItemObj.m_revPtrVec).end()) {
    (this->m_revPtrVec).push_back(new ItemRev(**vecIter));
  }
}

=========

// Derived classes
class JDI_ItemRev : public ItemRev {
  ...
}

class JDI_Item : public Item {

...

}

JDI_Item::JDI_Item(const JDI_Item &itemObj)
{
  // Copy contents of the input object's item rev pointer vector
  vector<ItemRev *>::const_iterator vecIter = (inputItemObj.m_revObjPtVec).begin();

  // The below does not work!
  while (vecIter != (inputItemObj.m_revObjPtVec).end()) {
    m_revObjPtVec.push_back(new JDI_ItemRev(**vecIter));
  }
}

上述问题出现在push_back()复制构造函数的JDI_Item调用中。

鉴于此设置,子类的复制构造函数应该是什么样的?我甚至需要一个子类复制构造函数吗?我假设我这样做,因为复制构造函数正在创建新对象,并且父复制构造函数将创建新的对象,这些对象不是派生类中我想要的类型(即,父对象存储指向ItemRev对象的指针,而子对象应该存储指向派生的JDI_ItemRev对象的指针。

1 个答案:

答案 0 :(得分:1)

正如评论中所提到的,可能有一种更简洁的方式来表达这个问题(即你的班级结构需要一些工作)。

但是,如果你想这样做,最简单的方法是在ItemRev的基类中使用虚拟clone()方法,并在派生类中定义它的覆盖。 / p>

e.g:

class ItemRev {

  virtual ItemRev* clone() const = 0;
};

class JDI_ItemRev : public ItemRev {

  ItemRev* clone() const override 
  {
    // do your actual cloning here, using the copy constructor
    return new ItemRev(*this);
  }
};

现在,无论何时在clone()派生的任何类上调用ItemRev,您都将返回ItemRev*,但它将指向完全构造的派生类。您当然可以使用static_cast<>dynamic_cast<>来获取派生类的界面。

... ...然而

推导通常看似简单的胜利,但事实证明并非如此。仅当派生类确实是基类的类型时,才应使用继承。通常人们在派生类很像基类时选择继承,或者基类共享许多特征。现在不是使用继承的时候。现在是使用封装的时候了。

一般来说,继承是邪恶的。

另一方面,您可能会发现此链接很有趣。

Presentation on inheritance as an implementation detail