我想使用for循环遍历抽象类list<abstract>
的列表。
这是我的代码:
class Component {
protected:
string name;
int price;
public:
Component(string name, int price): name(name), price(price){};
virtual int getPrice() =0;
};
class Composite : public Component {
list<Component> components;
public:
int getPrice() {
for(Component comp : components) {
return comp.getPrice();
}
}
};
class Leaf : public Component {
public:
int getPrice() {
return price;
}
};
但是我得到一个错误;无法分配抽象类型为'Component'的对象。这个错误是有道理的,因为不能实例化抽象类型。
答案 0 :(得分:1)
您的代码有一些问题:
您声明virtual int getPrice() = 0;
,这将使您的Component
成为纯虚拟->您无法实例化该对象的对象-> list<Component> components;
显得没有意义。请考虑改用list<Component*>
(或智能指针)!
基于范围的for循环:
for(Component comp : components) {
return comp.getPrice();
}
假设您已将列表更新为list<Component*>
,则for循环可能是:
for(auto& comp : components) {
return comp->getPrice();
}
答案 1 :(得分:1)
list<Component>
表示list
只能包含类型完全为Component
的对象。它不能包含其他类型的对象(即使从Component派生)。
由于无法创建Component
类型的(完整)对象,因此该列表不可用。
要创建一个列表,该列表可以存储具有Component
作为基类的任何对象,则必须通过引用存储列表项。但是随后您必须考虑列表中对象的生命周期管理。
一种方法是:
std::list< std::shared_ptr<Component> > components;
,循环可能是:
for(auto& comp : components) {
return comp->getPrice();
}
(尽管为什么总是在第一个项目上退出时才使用循环是另一个问题)。
还有其他可用选项代表不同的所有权语义。我建议阅读有关C ++中智能指针的指南,以进一步理解该主题。
答案 2 :(得分:0)
您必须指出您想要参考:
for(Component & comp : components)
或者简单地
for(auto & comp : components)
如果需要(或需要),还可以添加const
修饰符。
for(const Component & comp : components)
注意
虽然我的分析服务可能不完整,但确实可以解释问题中报告的错误。正如其他尚未报道的那样,按值创建抽象对象列表是没有意义的。
但是,问题也是与循环相关的问题。因此,对于这个问题,我认为我的回答是足够的。