nabacc001
nabacc001

Reputation: 13

Passing a pointer to one derived class to another

I'm still learning basics of c++, but I'm currently working on a project using derived classes and virtual methods. So the situation is: I have a ClassA

class ClassA
{
public:
    virtual void action();
};

And there are two derived classes B and C:

#include "ClassA.h" 

class ClassB: public ClassA
{
public:
    virtual void action();
    int valueB;
};

-

#include "ClassA.h"

class ClassC: public ClassA
{
public:
    virtual void action();
    int valueC;
};

I want to pass a pointer to an object of ClassB as a parameter of action() in ClassC, so I can do something like this:

void ClassC::action(ClassB * ptr)
{
cout << "The value is: " << ptr->valueB;
}

However I cannot find a working way to do it. All of the object pointers are stored in a

vector<ClassA *> objects

where

objects[0]=new ClassC();
objects[1]=new ClassB();

if I try something like

objects[0]->action(object[1])

then I need my virtual method in ClassA to have a parameter ClassB *. And then for a program to recognise the type I tried either including entire ClassB.h (bad idea, it creates a "loop" of includes or something) or using a forward declaration class ClassB; (I get an error about invalid use of incomplete type). And so I'm currently stuck. I hope that everything is clear, but I can of course provide more datails if needed.

Upvotes: 1

Views: 150

Answers (3)

Adam J Richardson
Adam J Richardson

Reputation: 363

I notice your ClassC virtual function is declared as taking no parameters:

virtual void action();

but you define your derived class function with a parameter.

void ClassC::action(ClassB * ptr)

The declaration and definition must match. Change the declaration to:

virtual void action(ClassB *);

Hmm. But then you must either include ClassB before the ClassC declaration...

#include "ClassB.h"

or forward declare ClassB. This is a promise to the compiler to properly declare and define the class later. A good place to insert this line would be just before the ClassC declaration.

class ClassB;

Upvotes: 1

Dieter Meemken
Dieter Meemken

Reputation: 1967

You could define action (in all classes) as:

virtual void action(ClassA * ptr); // or ClassB *

Then you can pass any instance of ClassA or derived from ClassA. All derived classes can include ClassA with #include "ClassA.h", if you provide the Sentinel in the header-File as it is common in c++ :

#ifndef ClassAH
#define ClassAH

...

#endif

So, the header will be included only once...

Upvotes: 0

Jack
Jack

Reputation: 133669

When you need to forward declare something it is because you can't include the whole definition of the class. In this situation if you forward declare ClassB the compiler doesn't know about its member attribute valueB, that's why you get an incomplete type error. To solve this problem you have to factor code something like:

//ClassA.h
class ClassB;

class ClassA
{
  virtual void action(ClassB* ptr);
}

//ClassA.cpp
#include "ClassB.h"
void ClassA::action(ClassB* ptr) { ... }

So you are basically using the header to declare the virtual method and forward declare ClassB, but you define it in ClassA.cpp, so that in the source file you can include ClassB.h with no problems and no risks of circular dependencies.

Upvotes: 2

Related Questions