将继承的类类型作为参数传递给采用其基类类型的方法时,我遇到了问题。
class Base {...}
class Derived : public Base {...}
class Container {
vector<Base*> cont; //1
public:
void addToCont(Base x) { //2
cont.push_back(&x);
}
}
int main() {
Container c;
c.addToCont(Derived(p1,p2)); //3
}
1)我想我需要有一个指向对象的指针容器以使其正常工作
2)这是从派生到基数转换中的错误
3)我不应该更改此电话。我试过了
Derived d(p1,p2);
c.addToCont(d);
与
addToCont(Base& x)
它为我工作。
我的问题是我有3个派生类,并且我不想3次重载add方法。我想我将不得不向这些类添加一些虚拟方法或类型转换,但是我对此一无所获。我是继承的新手,对此感到很困惑。感谢你的帮助。
最佳答案
一些注意事项:
必须使用指向Base的指针向量,以便可以处理层次结构中的对象。不用说,使用某种智能指针而不是原始指针可能会更好,但这会带来偏好,以及您有多爱冒险。
使用void addToCont(Base x)
是错误的,因为即使您仅添加基础对象,也将添加指向本地变量的指针(值传递参数)
同样,使用void addToCont(Base &x)
与本地Derived d
进行操作的方式也是错误的,由于与以前相同的原因,一旦d
超出范围,您将留下一个悬空的指针,该指针存储在指针中
调用addToCont(Derived(...))
会传递一个临时对象。在考虑内存管理时,必须考虑到这一点。
不知道为什么您需要为所有派生类重载addToCont,这不是您在void addToCont(Base &x)
上所做的
解决方案(如果您保留原始指针的话)是在void addToCont(Base *x)
中执行,您可以将指针传递给Base或任何Derived。同样,您必须注意内存管理。您可能需要为您的派生对象分配一个new Derived(...)
,并且您必须注意谁拥有它,以及谁负责删除它(例如,当Container对象被销毁时)。
您可能应该记住使虚拟对象成为Base的析构函数,因为您将破坏Base指针中的Derived对象,并且如果析构函数不是虚拟的,则对象将仅被部分破坏。
如果绝对需要addToCont(Derived(...))
调用,则您可能要考虑使用void addToCont(Base &x)
定义...。但是,在将它们插入向量中之前,您必须先克隆该对象:
void addToCont(const Base &x) { //2
cont.push_back(x.clone());
}
但是然后..您需要(至少)在Derived类中实现一个
virtual Base *clone() const
方法,该方法将产生一个带有Derived对象的精确副本的Base指针,涉及对象的额外副本和额外的克隆...