通过引用C++中的基类来循环遍历派生类

Looping through the derived classes by referencing the base class in C++

本文关键字:循环 遍历 派生 基类 引用 C++      更新时间:2023-10-16

很抱歉,如果以前有人问过这个问题,刚刚学习C++,曾尝试过搜索,但不确定关键字是什么。

有可能这样做吗?

class Car {
   public:
      void addColor(string c) {
          color = c;
      }
   private:
      string color;
}
class Honda:public Car {}
class Toyota:public Car {}
int main() {
    vector<Car> v;
    Honda *car1 = new Honda();
    car1.addColor("green");
    Toyota *car2 = new Toyota();
    car2.addColor("blue");
    v.push_back(car1);
    v.push_back(car2);
    for (int i = 0; i < v.size(); i++) {
        cout << v[i].color << endl; // should output green, blue
    }
}

如果可能的话,最正确/最有效的方法是什么?

编辑1

哇,谢谢大家!

您的向量始终保持基类型Car切片。查找"多态STL集合"多态向量"或类似内容,了解如何存储派生类。

这是一个的例子

有两种方法可以处理此问题。假设我们有以下类定义:

#include <string>
class Car {
   public:
      Car(const std::string& color) : color(color) {}
      virtual ~Car() {}
      std::string color;
};
class Honda:public Car {};
class Toyota:public Car {};

注意,我删除了setter,只是公开了该成员。你可能想要也可能不想要,但对于这个例子来说,这并不重要。这里有一种方法,可以分配堆栈上的所有内容,并获取这些对象的地址。在本例中,这很好(car1car2不需要比main函数更长寿)。在实际代码中,这可能不是真的(即,对象可能需要比创建它们的函数更长寿,请参阅下文):

#include <iostream>
#include <vector>
int main() {
    Honda car1("green");
    Toyota car2("blue");
    std::vector<Car*> cars; // vector of non-owning pointers
    v.push_back(&car1);
    v.push_back(&car2);
    for(auto& car : cars) {
        std::cout << car.color << "n";
    }
}

或者,在堆上分配对象:

int main() {
    std::vector<std::unique_ptr<Car>> cars; // vector of owning pointers
    v.emplace_back(new Honda("green"));
    v.push_back(new Toyota("blue"));
    for(auto& carptr : cars) {
        std::cout << carptr->color << "n";
    }
}

你走在正确的道路上,只有一些小问题需要解决:

  • 将getter添加到基类(Car
  • 更改矢量类型(为vector<Car*>
  • 需要时,用a->b替换a.b
  • 修复类定义后缺少分号的问题

给你:

#include <iostream>
#include <vector>
using namespace std;
class Car {
   public:
      virtual ~Car ();
      void addColor(string c) {
          color = c;
      }
      string getColor () {
          return color;
      }
   private:
      string color;
};
class Honda:public Car {};
class Toyota:public Car {};
int main() {
    vector<Car*> v;
    Honda car1;
    car1.addColor("green");
    Toyota car2;
    car2.addColor("blue");
    v.push_back(&car1);
    v.push_back(&car2);
    for (int i = 0; i < v.size(); i++) {
        cout << v[i]->getColor () << endl; // should output green, blue
    }
}

顺便说一句,如果你想让你的子类有自己的方法来处理颜色,只需在car类中将这些方法声明为virtual,你就可以在子类中重新定义它。

还有一点。你不能使你的向量是vector<Car>。因为子类的大小可能与母类的大小不同(想象一下,将int appeal;添加到Honda类中),因为向量只能存储大小相同的元素。