2

Im learning C++, and I am trying to do a little app. My app takes an informal ticket (without TAX) like this:

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

Where the first line is the number of items

In the second and third line= type of tax + title + price without TAX

The items can be of different types: books(TAX type 3), toys(TAX type 1)

All types inherit from the class article, but depending of the TAX type the price will be different (polymorphism).

I need to store all items (different types) in an array, how can I do it?

3
  • 2
    I heard that you cannot do such a thing, but you can store pointers to items in an array. Commented Jan 17, 2016 at 1:11
  • This question is very broad and the example is not very well motivated. Probably you should simply store a std::vector<std::unique_ptr<article>> or the like as @MikeCAT hints you. There are ways to simulate polymorphism in contiguous storage containers but they are probably too advanced at this point and I doubt that your program will ever need it for any real reason. Commented Jan 17, 2016 at 1:16
  • Also, the example you give does not seem to need different types. The tax type should be an attribute to your objects, not a cause to differentiate classes... what will happen when the government decides that text books (and only text books) pay a different tax. Create a whole new class and recodify all of your code? Commented Jan 17, 2016 at 1:19

4 Answers 4

1

You can store pointers in the array.

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;
}

output:

A: 1
B: 1.5
A: -5
B: 0
Sign up to request clarification or add additional context in comments.

Comments

0

Maybe you can try boost::variant library, it act as a wrapper around anything. then you can store many boost::variant wrapper in an array

Comments

0

if I understood your question correctly, you need to know how to define an array of your base class with it's derived classes. If this is the case, you can do it by defining an array in the base class, which in your case would look something like this:

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

Comments

0

All types inherit from the class article, but depending of the TAX type the price will be different (polymorphism).

type or TAX type could be stored as a member in Class article.

No polymorphism is needed here.

The items can be of different types: books(TAX type 3), toys(TAX type 1)

Or you could store only the type (books, toys), and do a lookup in a table type | TAX-type, if the TAX types will always be the same for the full range of each type.


But if you really have or need a derived class for each type (for example to store different properties), you could call a virtual function in the derived classes CalcTax() for example.

An array with (baseclass*) pointers to the items could be created, and you can loop through that array, and call CalcTax() on each item, which will call the correct virtual function.

For example:

#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;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.