user3653164
user3653164

Reputation: 1089

C++ accessing member of subclass of abstract class pointer vector

Error over here:

Rocket.cpp:31:16: error: no member named 'getThrust' in 'RocketPart'
    rocket[0]->getThrust();

When I want to access getThrust() from class Engine over the vector<RocketPart*> rocket with rocket[i]->getThrust(), I get the error message from the top of my question. What am I doing wrong? Is it possible to access it over rocket[index]->getThrust()?

Upvotes: 3

Views: 1289

Answers (5)

Vincenzo Cappello
Vincenzo Cappello

Reputation: 91

The method getThrust() is defined in the Engine class not in the RocketPart. You need to move the method in the base class RocketPart, for access it over the vector. Alternatively you can also use a dynamic cast for "convert" the RocketPart to the Engine.

Engine* engine = dynamic_cast<Engine>(rocket[index]);
if (engine) {
    engine->getThrust();
}

Consider that the use of dynamic_cast often means bad design.

Upvotes: 0

sirgeorge
sirgeorge

Reputation: 6541

You need to add

virtual float getThrust() = 0;

In your RocketPart class. Besides, I can see absolutely no reason to use virtual inheritance (this is only needed if you inherit from multiple classes and you have The Diamond Problem), so instead:

class Engine : virtual public RocketPart {

you should be ok with just :

class Engine : public RocketPart {

I would also suggest looking at your memory allocation(s) - if your sample source code is not just an example (you are leaking Engine objects, maybe vector<shared_ptr<Engine>> would be a better idea ?)

Upvotes: 0

Tas
Tas

Reputation: 7111

The error you receive is correct: there is no function called getThrust in the class RocketPart. You can either:

  • add a virtual float getThrust() to your RocketPart class. This may not be a good solution, because not all RocketPart could contain thrust; however, you could simply return 0 from it, or make it a pure virtual function (which would mean you are no longer to ever create a RocketPart object
  • dynamic_cast your RocketPart object into an Engine. This can be done with the following:

    for (size_t r = 0; r < rocket.size(); ++r) { if (const Engine* engine = dynamic_cast<Engine*>(rocket[r])) { // able to successfully convert this RocketPart into an Engine engine.getThrust(); } }

You will not be able to cast any RocketPart* that isn't an Engine

Upvotes: 1

Seb
Seb

Reputation: 73

it is because the type stored in the container is RocketPart. You need to downcast the pointer to Engine. So instead of

rocket[0]->getThrust();

you need to write:

Engine *pPart = (Engine *) rocket[i]; //you can use also static_cast<> or dynamic_cast<>
pPart->getThrust();

Be careful when using cast: if rocket[i] is not an Engine, the program will likely crash.

Upvotes: 0

Lawrence Aiello
Lawrence Aiello

Reputation: 4668

The class RocketPart does not have a function getThrust() inside of it, which is why your vector calling the function doesn't work. If getThrust() is a common routine that will be used in the classes inheriting from it, you should add it as a virtual function in the base class like so:

class RocketPart {
public:
    RocketPart();
    RocketPart(const RocketPart& orig);
    virtual ~RocketPart();

    virtual float getThrust();

    virtual void print() = 0;
protected:
    // some members
};

Upvotes: 2

Related Questions