我遇到了复制构造函数的问题......我假设有一个基本的答案,我错过了一些明显的东西 - 也许我做错了什么 - 但我我们无法弄明白。
基本上,我有一个父类和子类。父类包含指向(不同的)基类对象的指针向量。子类想要存储指向从该基础对象派生的对象的指针。
这是一个伪代码样本,如果有帮助的话:
// 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
对象的指针。
答案 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<>
来获取派生类的界面。
... ...然而
推导通常看似简单的胜利,但事实证明并非如此。仅当派生类确实是基类的类型时,才应使用继承。通常人们在派生类很像基类时选择继承,或者与基类共享许多特征。现在不是使用继承的时候。现在是使用封装的时候了。
一般来说,继承是邪恶的。
另一方面,您可能会发现此链接很有趣。