基于范围的for循环,其中抽象类为声明C ++

时间:2019-01-14 02:56:42

标签: c++ loops class

我想使用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'的对象。这个错误是有道理的,因为不能实例化抽象类型。

3 个答案:

答案 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)

注意

虽然我的分析服务可能不完整,但确实可以解释问题中报告的错误。正如其他尚未报道的那样,按值创建抽象对象列表是没有意义的。

但是,问题也是与循环相关的问题。因此,对于这个问题,我认为我的回答是足够的。