0

I would like to write a little program where the piece of code does not need to know what exactly is the object it is dealing with, while it could use an interface of that object.

In my imagination, this would be kind of an "interface accessed through an interface". But even if it compiles, it crashes. This is my code (tried in CodeBlocks):

#include <iostream>
#include <string>

using namespace std;

class ToyInteractor {
public:
    ToyInteractor() {};

    virtual void interFunc() = 0;
};

class HorseInteractor : public ToyInteractor {
public:
    HorseInteractor() {};
    ~HorseInteractor() {};

    void interFunc() override { cout << "We made it inside HorseInteractor!" << endl; };
};

class BirdInteractor : public ToyInteractor {
public:
    BirdInteractor() {};
    ~BirdInteractor() {};

    void interFunc() override { cout << "We made it inside BirdInteractor!" << endl; };
};


class Toy {
public:
    Toy() {};

    ToyInteractor *toyInteractor;
    virtual void func() = 0;
};

class Horse : public Toy {
public:
    Horse() {};
    ~Horse() {};

    ToyInteractor *toyInteractor = new HorseInteractor();
    void func() override { cout << "We made it inside Horse!" << endl; };
};

class Bird : public Toy {
public:
    Bird() {};
    ~Bird() {};

    ToyInteractor *toyInteractor = new BirdInteractor();
    void func() override { cout << "We made it inside Bird!" << endl; };
};



int main()
{
    Horse *horse = new Horse();
    Bird *bird = new Bird();

    // Works as expected
    horse->func();
    bird->func();
    cout << endl;

    // Also works of course
    horse->toyInteractor->interFunc();
    bird->toyInteractor->interFunc();
    cout << endl;


    // Now suppose we do not know the exact type, but we know it surely has a toy-specific toyInteractor:
    Toy *someToy = horse;

    // Works fine:
    someToy->func();

    // 1. idea: Crashes:
//    someToy->toyInteractor->interFunc();

    // 2. idea: Also crashes:
//    ((HorseInteractor*)(someToy->toyInteractor))->interFunc();

    return 0;
}

Could someone please give a thorough explanation why the 1st and 2nd ideas are not working here?

Thank you very much, I appreciate any help!

Yksisarvinen
  • 18,008
  • 2
  • 24
  • 52
  • 2
    `toyInteractor` you declare in `Horse` and `Bird` are completely different members than `toyInteractor` in `Toy`. There is no such thing as member overriding. So for example `Bird` has its own member `toyInteractor`, which is initialised, but it also has `toyInteractor` inherited from `Toy`, which is **not** initialised. – Yksisarvinen Jul 26 '23 at 09:41
  • Also, do note that your base classes should have a `virtual` destructor, otherwise `delete someToy;` will invoke Undefined Behaviour. – Yksisarvinen Jul 26 '23 at 09:46

0 Answers0