1

I'm new to C++ programming so this question might be basic, but here it is:

I have four classes - A, B, C and D. Their relationships are as defined below:

class B : public A;
class D : public C;

A is an abstract class (all methods are pure virtual). Class D implements a Print() function which C does not.

//Class D - some code
void Print()
{
    //some code
}

Class A has an STL::list that holds pointers to objects of class C.

//Class A - some code
protected:
    list<C*> myObjects;

In class B I have a function which pushes to myObjects pointers to objects of type D (again, D inherits C) which works perfectly.

Class B : public A
{
    // Some code
    D* obj = new D(...);
    myObjects.push_back(obj);
    return obj;
}

Finally, in class B I have a function that iterates over myObjects (which is inherited from class A) like so:

for(list<C*>::iterator it = myObjects.begin(); it != myObjects.end(); it++)
{
    //I wish to call the function D.Print() but I get an error!
    D *a = *it;
    a->Print();
}

Error states:

error C2440: 'initializing': cannot convert from 'std::_List_iterator<_Mylist>' to 'D*'

I am under the impression that if "a" is a pointer to an object of class D, then if I give it the value of the pointer that is referenced by the iterator (which points to a pointer to an object of type D) I could call Print().

Can you help? Thanks in advance!

Tal
  • 398
  • 4
  • 19
  • @juanchopanza I tried that but since Print is not defined in class C, I get C2039: 'Print' : is not a member of C. – Tal Apr 02 '14 at 08:51
  • Sorry, i had missed that part. Then you need to try a `dynamic_cast`. It is better to have the relevant information in code, rather than prose. – juanchopanza Apr 02 '14 at 08:52
  • Instead of just trying to explain what you have, with small out-of-context code snippets, why not create a [Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve) that you can show us? It will make it much easier to understand what you have and what might be going on. – Some programmer dude Apr 02 '14 at 08:58
  • I will remember that for my next questions. Thanks for the tips. – Tal Apr 02 '14 at 09:00

3 Answers3

2

There's no need to attempt to cast to a D type if you define

virtual void Print() = 0;

in class C.

Then you can exploit polymorphism by writing

C *a = *it;
C->Print();

or, even better,

(*it)->Print();

If you can't do this then you could use a dynamic_cast, or simply store list<D*> myObjects; instead.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
1

Try

D *a=dynamic_cast<D *>(*it)

The content of the list might be D objects, but that's only known at runtime, so the compiler cannot know at compile time if the list contain's D objects or other derived class from C.

For the record, this code compiled on ideone

jsantander
  • 4,972
  • 16
  • 27
  • I get error C2683: 'dynamic_cast' : C is not a polymorphic type – Tal Apr 02 '14 at 08:53
  • @Tal You said that C has virtual methods... tried a dummy example with g++ and it worked. – jsantander Apr 02 '14 at 08:56
  • I was wrong. A is abstract. C is not. Sorry for the confusion - I edited the original question. – Tal Apr 02 '14 at 09:03
  • 1
    then use static_cast instead.... however, depending on how you handle things... you probably would need a virtual destructor on C – jsantander Apr 02 '14 at 09:06
  • This might be relevant: (http://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-const-cast-and-reinterpret-cast-be-used) – jsantander Apr 02 '14 at 09:07
0

Make sure that Print is declared as pure virtual in C, and then just use the C pointer instead of D in your print loop. You do not need any casting, that's what virtual functions are for.

Wojtek Surowka
  • 20,535
  • 4
  • 44
  • 51