我可以使用多态来使用C ++在数组中存储不同的对象吗?

时间:2016-01-17 01:09:15

标签: c++ arrays inheritance polymorphism

我正在学习C ++,我正在尝试做一个小应用程序。我的应用程序采用这样的非正式票证(没有TAX):

2
3 Mi_primera_tablet 7.95
1 El_general_en_su_laberinto Gabriel_García_Márquez 23.50

第一行是项数

在第二行和第三行= type of tax + title + price without TAX

项目可以是不同类型:书籍(TAX类型3),玩具(TAX类型1)

所有类型都继承自类文章,但根据TAX类型,价格会有所不同(多态)。

我需要将所有项目(不同类型)存储在一个数组中,我该怎么办?

4 个答案:

答案 0 :(得分:1)

您可以在数组中存储指针。

Exapmle(c ++ 11):

#include <iostream>
#include <vector>
#include <memory>

struct A {
  int value;
};


struct B {
  double item;
};


class Element {
 public:
  explicit Element(A a);
  explicit Element(B b);

  const A * AsA() const;
  const B * AsB() const;

 private:
  class AbstractElement {
   public:
    virtual ~AbstractElement() {
    }

   protected:
    AbstractElement() {
    }
  };

  template <typename T>
  struct ConcreteElement : public AbstractElement {
    T body;

    explicit ConcreteElement(T input_body)
        : body(std::move(input_body)) {
    }
  };

  std::unique_ptr<AbstractElement> element_;
};

Element::Element(A a)
    : element_(new ConcreteElement<A>(a)) {
}


Element::Element(B b)
    : element_(new ConcreteElement<B>(b)) {
}


const A * Element::AsA() const {
  const auto concrete_element =
      dynamic_cast<ConcreteElement<A> *>(element_.get());
  return concrete_element ? &(concrete_element->body) : nullptr;
}

const B * Element::AsB() const {
  const auto concrete_element =
      dynamic_cast<ConcreteElement<B> *>(element_.get());
  return concrete_element ? &(concrete_element->body) : nullptr;
}


int main() {
  std::vector<Element> values;
  values.push_back(Element(A{1}));
  values.push_back(Element(B{1.5}));
  values.push_back(Element(A{-5}));
  values.push_back(Element(B{0}));

  for (const auto & element : values) {
    const auto p_a = element.AsA();
    if (p_a) {
      std::cout << "A: " << p_a->value << std::endl;
    } else {
      const auto p_b = element.AsB();
      std::cout << "B: " << p_b->item << std::endl;
    }
  }
  return 0;
}

输出:

A: 1
B: 1.5
A: -5
B: 0

答案 1 :(得分:0)

如果我正确理解了你的问题,你需要知道如何使用它的派生类来定义基类的数组。如果是这种情况,您可以通过在基类中定义一个数组来实现,在您的情况下,该数组看起来像这样:

article ArrayName [n];
Books Books = new Books();
//do some thing with the books object
ArrayName[0] = Books;

答案 2 :(得分:0)

  

所有类型都继承自类文章,但取决于TAX   键入的价格会有所不同(多态)。

typeTAX type可以存储为Class article中的成员。

这里不需要多态性。

  

项目可以是不同类型:书籍(TAX类型3),玩具(TAX类型   1)

或者您只能存储类型(bookstoys),并在表type | TAX-type中进行查找,如果TAX类型在整个范围内始终相同每种类型。

但是如果你真的拥有或需要每种类型的派生类(例如存储不同的属性),那么可以在派生类CalcTax()中调用虚函数。

可以创建一个包含指向项目的(基类*)指针的数组,然后循环遍历该数组,并在每个项目上调用CalcTax(),这将调用正确的虚函数。

例如:

#include <iostream>

class Base
{
public:
    virtual CalcTax() = 0;
};

class Type_1 : public Base
{
public:
    virtual CalcTax() {std::cout << "Type_1\n";}
};

class Type_2
{
public:
    virtual CalcTax() {std::cout << "Type_2\n";}
};

int main()
{
    Base *arrItems[2]; // or better use std::vector<> etc.
    Type_1 t1;         // just a quick demo of polymorphism
    Type_2 t2;
    arrItems[0] = (Base*)&t1;
    arrItems[1] = (Base*)&t2;

    for (int i = 0; i < 2; ++i) {
        arrItems[i]->CalcTax();
    }

    return 0;
}

答案 3 :(得分:0)

也许你可以尝试使用boost :: variant库,它可以充当任何东西的包装器。那么你可以在数组中存储许多boost :: variant包装器