c++ - 区分 C++ 中基指针向量中的派生对象
问题描述
跟进这个问题 Vector/Container 由 C++ 中的不同派生对象组成,我试图改进我的代码。现在我将指向派生对象的指针存储在单个向量中,但我不确定如何访问它们的派生类特定成员函数并将单个向量拆分为每个派生类型的子向量。
#include <vector>
#include <memory> // for unique_ptr
#include <iostream>
using namespace std;
class Fruit {};
class Banana: public Fruit { void cout_banana() { cout << "i am a banana" << endl; } };
class Apple : public Fruit { void cout_apple() { cout << "i am an apple" << endl; } };
class FruitBox
{
vector<unique_ptr<Banana>> vec_banana;
vector<unique_ptr<Apple>> vec_apple;
public:
FruitBox(const vector<unique_ptr<Fruit>> &fruits)
{
for (const unique_ptr<Fruit> &f : fruits)
{
// How to figure out if f is Banana or Apple and then
// 1) Print either cout_banana or cout_apple
// 2) Store/Move f in either vec_banana or vec_apple
}
}
};
void main()
{
vector<unique_ptr<Fruit>> inputs;
inputs.emplace_back(new Banana());
inputs.emplace_back(new Apple());
FruitBox fbox = FruitBox(inputs);
}
解决方案
我认为你的问题不是实现本身(检查实际的类可以使用dynamic_cast
,但我不会在这里深入探讨,因为它是不必要的),而是你首先对面向对象的理解 - 至少在这个特殊的例子。
Liskov 替换原则指出“如果 S 是 T 的子类型,则类型 T 的对象可以替换为类型 S 的对象(即类型 T 的对象可以替换为子类型 S 的任何对象)。” 这不是这里的情况。
与其在子类中定义,不如cout_xyz
在子类中编写void cout_fruit()
抽象方法class Fruit
并覆盖它。
class Fruit { public: virtual void cout_fruit() = 0; };
class Banana: public Fruit { public: void cout_fruit() override { cout << "i am a banana" << endl; } };
class Apple : public Fruit { public: void cout_fruit() override { cout << "i am an apple" << endl; } };
// [...]
然后,对于每个水果,您可以简单地调用f->cout_fruit()
.
推荐阅读
- arrays - 如何使用这两个输入数组基于范围创建平铺/堆叠数组 - 但不循环?
- c# - .NET、C#、反射 GetMethod 返回 null(试图在第三方 dll 中获取方法)
- asp.net-core - “JsonConvert”类型中不存在类型名称“serializeObject”
- sql - 与前导零连接几个月 - 不是有效的月份错误
- spring - 如何在 SpringBoot 中测试 Kafka 客户端配置
- regex - Bash 从字符串中查找主题标签
- java - XSLT - 迭代列表时访问 Java 对象时出错
- jquery - 我正在尝试从 jquery 元素中捕获类的其余部分
- ios - 如何从完成处理程序中返回值(特殊情况)?
- javascript - 使触摸设备上的缩放行为更像在桌面上