简体   繁体   English

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

[英]Range-based for loop with abstract class as declaration C++

I want to iterate through a list of an abstract class list<abstract> using a for loop. 我想使用for循环遍历抽象类list<abstract>

Here's my code: 这是我的代码:

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;
        }
};

But I get an error; 但是我得到一个错误; cannot allocate an object of abstract type 'Component'. 无法分配抽象类型为'Component'的对象。 This error makes sense, as abstract types can't be instantiated. 这个错误是有道理的,因为不能实例化抽象类型。

Your code has some problems: 您的代码有一些问题:

You declare virtual int getPrice() = 0; 您声明virtual int getPrice() = 0; and this makes your Component pure virtual -> you CANNOT instantiate an object of it -> list<Component> components; 这使您的Component纯虚拟的->您无法实例化其对象-> list<Component> components; does NOT make sense to appear. 出现没有意义。 Please consider to use list<Component*> (or smart-pointer) instead! 请考虑改为使用list<Component*> (或智能指针)!

Range-based for loop: 基于范围的for循环:

for(Component comp : components) {
    return comp.getPrice();   
}

Suppose you have updated your list to list<Component*> then the for loop could be: 假设您已将列表更新为list<Component*>则for循环可能是:

for(auto& comp : components) {
    return comp->getPrice();   
}

list<Component> means the list can only contain objects whose type is exactly Component . list<Component>意味着list只能包含类型完全是Component对象。 It cannot contain objects of some other type (even if derived from Component). 它不能包含某种其他类型的对象(即使从Component派生)。

Since it is not possible to create (complete) objects of type Component , this list is not usable. 由于无法创建(完整) Component类型的对象,因此该列表不可用。

To create a list which can store any object having Component as a base class, the list items must be stored by reference. 若要创建可以存储以Component为基类的任何对象的列表,则必须通过引用存储列表项。 But then you have to think about lifetime management of the objects in the list. 但是随后,您必须考虑列表中对象的生命周期管理。


One way to do this would be: 一种方法是:

std::list< std::shared_ptr<Component> > components;

and the loop might be: 循环可能是:

for(auto& comp : components) {
     return comp->getPrice();   
} 

(although why you're using a loop when you always exit on the first item is another question). (尽管为什么总是在第一个项目上退出时却使用循环,这是另一个问题)。

There are other options available too which represent different ownership semantics. 还有其他可用选项代表不同的所有权语义。 I would recommend reading a guide on smart pointers in C++ for further understanding of this topic. 我建议阅读有关C ++中智能指针的指南,以进一步理解该主题。

You have to indicate that you want a reference: 您必须指出您想要参考:

for(Component & comp : components)

Or simply 或者简单地

for(auto & comp : components)

If you want (or need), you can also add const modifier. 如果需要(或需要),还可以添加const修饰符。

for(const Component & comp : components)

Note 注意

While my anser might be incomplete, it does explain the error reported in the question. 虽然我的分析服务可能不完整,但确实可以解释问题中报告的错误。 As other have not reported, it make no sense to create a list of abstract object by value. 正如其他尚未报道的那样,按值创建抽象对象列表是没有意义的。

However the question was specific about the problem related to the loop too. 但是,问题也是与循环相关的问题。 As such, I think that my answer was adequate given the question. 因此,鉴于这个问题,我认为我的回答是足够的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM