首页 > 解决方案 > 区分 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);
}

标签: c++inheritancederived-class

解决方案


我认为你的问题不是实现本身(检查实际的类可以使用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().


推荐阅读