-8

can't understand how to properly inherit objects. There is my code:

#include <ArduinoSTL.h>

class Element {
public:
    Element() {

    };
    virtual void execute() {
        Serial.print("element\n");
    }
};
class ExtendedElement : public Element {
public:
    ExtendedElement() : Element() {

    }
    virtual void execute() {
        Serial.print("extended element\n");
    }
};
class Wrapper {
private:
    std::vector<Element> elements;

public:
    void execute() {
        for (Element element : elements) {
            element.execute();
        }
    }

    void addTask(Element element) {
        elements.push_back(element);
    }
};

Wrapper wrapper;

void setup() {
    Serial.begin(9600);
    ExtendedElement extendedElement = new ExtendedElement();
    wrapper.addTask(extendedElement);
}

void loop() {
    wrapper.execute();
}

So, I want to extend class, create an instance of this extended class, and put such instance into vector of base class. Then I want to iterate over elements in vector, and call child class function. Can't understand what I'm doing wrong.

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
degr
  • 1,559
  • 1
  • 19
  • 37
  • 1
    When there is something wrong, you have to describe what is wrong? Is there a compiler error? If yes, show it in your question (copy and paste it there). Does the code behave wrong? Then describe, what behavior you have expected and what behavior you are seeing. – chrisl Aug 05 '18 at 13:50
  • Vector of `Element` can only store objects of `Element` class. `ExtendedElement extendedElement = new ExtendedElement();` is also not valid, because right part produces a pointer. – user7860670 Aug 05 '18 at 14:26

2 Answers2

2

result of new should be assigned to a pointer

ExtendedElement *extendedElement = new ExtendedElement();

elements should be a vector of pointers

class Wrapper {
private:
    std::vector<Element*> elements;

public:
    void execute() {
        for (Element *element : elements) {
            element->execute();
        }
    }

    void addTask(Element *element) {
        elements.push_back(element);
    }
};
Juraj
  • 3,490
  • 4
  • 18
  • 25
1

You have discovered what's called object slicing. Your vector stores Element objects not ExtendedElement objects. When you add an ExtendedElement object to your vector it is converted to an Element (this is the slicing part) so your ExtendedElement methods will never be called.

To get around this you need to store pointers to Element objects in your vector. A pointer to an Element can point to an actual ExtendedElement object and using virtual functions ensures that the correct function for the actual type will be called.

john
  • 85,011
  • 4
  • 57
  • 81