【问题标题】:Differentiate between derived objects in vector of base pointers in C++区分 C++ 中基指针向量中的派生对象
【发布时间】:2018-10-31 23:02:48
【问题描述】:

跟进这个问题 Vector/Container comprised of different derived objects in 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++ inheritance derived-class


【解决方案1】:

我认为您的问题不是实现本身(可以使用dynamic_cast 检查实际类,但我不会在这里深入探讨,因为它是不必要的),而是您对面向对象的理解第一名 - 至少在这个特定的例子中。

Liskov Substitution Principle 声明 “如果 S 是 T 的子类型,则 T 类型的对象可以替换为 S 类型的对象(即 T 类型的对象可以替换为任何子类型的对象S)。” 这里不是这样。

您应该在class Fruit 中将void cout_fruit() 作为抽象方法编写并在子类中覆盖它,而不是在子类中定义cout_xyz

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-&gt;cout_fruit()

【讨论】:

  • 对于奖励积分,您可以将其更改为 virtual std::basic_ostream&amp; output_fruit(std::basic_ostream&amp;) 并实现一个调用它的 operator&lt;&lt;
猜你喜欢
  • 2021-05-20
  • 2013-02-03
  • 2011-11-04
  • 1970-01-01
  • 2014-08-11
  • 1970-01-01
  • 1970-01-01
  • 2018-12-24
  • 1970-01-01
相关资源
最近更新 更多