Virtual Instancing of Derived Class

C

crjjrc

Hi. I've got a hierarchy of classes and I'm storing pointers to a mid-
level class Der1 in a vector. These pointers point to a handful of
classes derived from Der1, and Der2 is one such class. Classes below
Der1 implement a virtual function Helper() from the Base class, and
this function is typically called from a base class method
GetInstance(). I'm getting an error from g++ that I don't fully
understand.

The code is:

--------------------------------------------
#include <iostream>
#include <vector>

class Base {
public:
virtual Base *GetInstance() {
std::cout << "in Base::GetInstance()" << std::endl;
return Helper();
}
virtual Base *Helper() = 0;
};

class Der1 : public Base {
public:
};

class Der2 : public Der1 {
public:
Der2 *Helper() {
std::cout << "in Der2::Helper()" << std::endl;
return new Der2();
}
};

int main() {

Der2 d2;
Der1 *d1 = &d2;

std::vector<Der1 *> der1s;

der1s.push_back(d1->GetInstance());

return 0;

}
--------------------------------------------

On compiling, g++ tells me:

woo.cpp: In function 'int main()':
woo.cpp:32: error: invalid conversion from 'Base*' to 'Der1*'
woo.cpp:32: error: initializing argument 1 of 'void std::vector<_Tp,
_Alloc>::push_back(const _Tp&) [with _Tp = Der1*, _Alloc =
std::allocator<Der1*>]'

It seems that the return value of Der2::Helper() is implicitly cast
from Der2 * to Base * by Base::GetInstance(). In order to fix this,
it seems I have to use dynamic_cast:

der1s.push_back(dynamic_cast<Der1 *>(d1->GetInstance()));

Is this the correct diagnosis and a suitable solution to this problem?
 
V

Victor Bazarov

crjjrc said:
Hi. I've got a hierarchy of classes and I'm storing pointers to a
mid- level class Der1 in a vector. These pointers point to a handful
of classes derived from Der1, and Der2 is one such class. Classes
below Der1 implement a virtual function Helper() from the Base class,
and this function is typically called from a base class method
GetInstance(). I'm getting an error from g++ that I don't fully
understand.

The code is:

--------------------------------------------
#include <iostream>
#include <vector>

class Base {
public:
virtual Base *GetInstance() {
std::cout << "in Base::GetInstance()" << std::endl;
return Helper();
}
virtual Base *Helper() = 0;
};

class Der1 : public Base {
public:
};

class Der2 : public Der1 {
public:
Der2 *Helper() {
std::cout << "in Der2::Helper()" << std::endl;
return new Der2();
}
};

int main() {

Der2 d2;
Der1 *d1 = &d2;

std::vector<Der1 *> der1s;

Make your vector store Base*.
der1s.push_back(d1->GetInstance());

The call to 'GetInstance' with 'd1' returns Base*. The vector you
declared needs Der1* to store. Conversion from Base* to Der1*
requires at least a static_cast, and a dynamic_cast is better.
That's what your compiler is telling you.
return 0;

}
--------------------------------------------

On compiling, g++ tells me:

woo.cpp: In function 'int main()':
woo.cpp:32: error: invalid conversion from 'Base*' to 'Der1*'
woo.cpp:32: error: initializing argument 1 of 'void std::vector<_Tp,
_Alloc>::push_back(const _Tp&) [with _Tp = Der1*, _Alloc =
std::allocator<Der1*>]'

It seems that the return value of Der2::Helper() is implicitly cast
from Der2 * to Base * by Base::GetInstance(). In order to fix this,
it seems I have to use dynamic_cast:

der1s.push_back(dynamic_cast<Der1 *>(d1->GetInstance()));

Is this the correct diagnosis and a suitable solution to this problem?

A better solution would be to make your vector store 'Base*'.

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top