在C++中,过滤多态派生类的向量的正确方法是什么?

huangapple go评论62阅读模式
英文:

In C++ what is the correct way to filter a vector of polymorphic derived classes?

问题

以下是翻译好的代码部分:

这里有一个显然简单的示例,可以编译并运行。

#include <iostream>
#include <vector>

using namespace std;

class Shape {
public:
    virtual double getArea() = 0;
};

class Circle : public Shape {
public:
    double getArea() { return 3.14; }
};

class Rectangle : public Shape {
public:
    double getArea() { return 42.0; }
};

int main() {

    vector<Shape*> shapes = { new Circle(), new Rectangle() };

    for (Shape* s : shapes) { cout << s->getArea() << endl; }

    return 0;
}

这段代码的结果是它会打印出向量中的每个形状。

我不知道如何按派生类类型过滤向量。例如,如何迭代遍历向量,并且仅对每个圆执行某些操作?

谢谢你。

英文:

Here is an obviously simple example that compiles and runs.

#include &lt;iostream&gt;
#include &lt;vector&gt;

using namespace std;

class Shape {
    public:
    virtual double getArea() = 0;
};

class Circle : public Shape {
    public:
    double getArea() {return 3.14;}
};

class Rectangle : public Shape {
    public:
    double getArea() {return 42.0;}
};

int main() {

    vector&lt;Shape*&gt; shapes = {new Circle(), new Rectangle()};

    for (Shape* s : shapes) { cout &lt;&lt; s-&gt;getArea() &lt;&lt; endl;}

    return 0;
}

The result is that it will print every Shape in the vector.

What I do not know how to do is to filter the vector by derived class type. For example, how to iterate over the vector and only do something for each Circle?

Thank You

答案1

得分: 5

Here is the translated content:

首先,如果您希望将圆形与其他形状区分对待,您应该考虑将它们简单地存储在其他形状之外。

但有时您希望大部分时间为所有形状执行相同的操作,而有时为圆形执行特殊操作。

在这种情况下,您将执行动态下转型以从指向 Shape 的指针转换为指向 Circle 的指针。如果它指向的 Shape 不是圆形,这将失败并产生一个空指针。

class Circle : public Shape {
public:
    double getArea() {return 3.14;}
    void circlesOnly() { std::cout << "Whee! I'm a circle!\n"; }
};

vector<Shape*> shapes = {new Circle(), new Rectangle()};

for (Shape *shape : shapes) {
    if (Circle *c = dynamic_cast<Circle *>(shape); c != nullptr)
        c->circlesOnly();
}

请注意,代码部分未进行翻译,仅提供原文。

英文:

First of all, if you want to treat Circle's differently from other shapes, you should consider simply storing them separately from other shapes.

But sometimes you want to do the same things for all shapes most of the time, and something special for Circles some of the time.

In such a case, you'd do a dynamic down-cast to get from a pointer to Shape to pointer to Circle. If the Shape it points to isn't a circle, this will fail and yield a null pointer.


class Circle : public Shape {
    public:
    double getArea() {return 3.14;}
    void circlesOnly() { std::cout &lt;&lt; &quot;Whee! I&#39;m a circle!\n&quot;; }
};


vector&lt;Shape*&gt; shapes = {new Circle(), new Rectangle()};

for (Shape *shape : shapes) {
    if (Circle *c = dynamic_cast&lt;Circle *&gt;(shape); c != nullptr)
        c-&gt;circlesOnly();
}

huangapple
  • 本文由 发表于 2023年5月25日 08:24:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76328165.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定