我将继承的类类型作为参数传递给采用其基类类型的方法时遇到了问题。
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)以下是从Derived转换为Base
的错误3)我不应该改变这个电话。我试过了
Derived d(p1,p2);
c.addToCont(d);
与
addToCont(Base& x)
它对我有用。
我的问题是我有3个派生类,而且我不想超载add方法3次。我想我将不得不为这些类添加一些虚拟方法或一些类型转换,但我无法找到任何相关内容。我是继承的新手,对此很困惑。谢谢你的帮助。
答案 0 :(得分:0)
派生类只有在引用或指针时才“可以使用”。如果将类转换为没有引用或指针的基类,则以后将无法将其用作派生类。
如果你实际上是在容器中存储指针,那么我会明确指出,所以:
class Container {
vector<Base*> cont;
public:
void addToCont(Base* x) {
cont.push_back(x);
}
~Container()
{
for(auto a : cont)
{
delete a;
}
}
}
主要是:
集装箱c; c.addToCont(new Derived(p1,p2));
请注意,在原始代码中,Derived(p1, p2)
将在调用addToCont(...)
后再次被销毁,因此您的数组将指向Derived类的“dead”元素。这可能不是你真正想要的(因为它使用该元素是未定义的行为,并且构建一个装满无用元素的容器是没有意义的)
答案 1 :(得分:0)
一些注意事项:
void addToCont(Base x)
是错误的,因为即使你只是添加一个Base对象,你也会添加一个指向局部变量的指针(pass-by-value参数)void addToCont(Base &x)
使用本地Derived d
的方式也是错误的,出于与以前相同的原因,只要d
超出范围,您就会离开指针存储在指针中的悬空指针addToCont(Derived(...))
会传递一个临时对象。当你考虑你的记忆管理时,必须考虑到这一点。void addToCont(Base &x)
void addToCont(Base *x)
那里你可以传递指向Base或任何Derived的指针。同样,你必须注意内存管理。您的Derived对象可能需要使用new Derived(...)
进行分配,您必须查看谁拥有它,以及谁负责删除它(例如,当Container对象被销毁时)。如果绝对需要addToCont(Derived(...))
调用,那么您可能需要考虑使用void addToCont(Base &x)
定义....但是,它们必须在将对象插入向量之前克隆该对象:
void addToCont(const Base &x) { //2
cont.push_back(x.clone());
}
但是......你需要在Derived类中实现(至少)一个virtual Base *clone() const
方法,这将生成一个Base指针,其中包含Derived对象的精确副本,涉及对象的额外副本和额外的克隆...