Reputation: 4761
#include <iostream>
class BarParent
{
virtual void fuz()
{
std::cout << "BarParent" << std::endl;
}
};
class BarChild : public BarParent
{
virtual void fuz()
{
std::cout << "BarChild" << std::endl;
}
};
class Foo
{
// ??BarParent bar;??
public:
Foo(BarParent bar);
};
What I seek is to store a copy of BarParent
that is passed to the constructor and let it reside in Foo
, while still calling the correct virtual function
This is an embedded application: Use of the heap is frown upon. So preferably, no heap
SUMMARY: To the best of knowledge, it cannot be done, becuase of the slicing problem (long story short the compiler cannot determine the size of generic Bar
and so on copying it type casts), so polymorphism cannot be achieved. Using templates might be a good idea, however, it defines multiple class
es Foo<typename BarType>
, as a result, doing a function
such as changeBar(BarParent)
, would not be possible since the compiler would define this as changeBar(BarType)
defined only for class Foo<Bartype>
. If someone has a better idea, please let me know.
I think i will have to go for heap, or const Barparent
and pointers. If the user const_cast
s, then he is asking for trouble, not my fault!
Upvotes: 0
Views: 50
Reputation: 31952
class Foo
{
BarParent* bar; //or std::unique_ptr<>
public:
Foo(BarParent* barInst):bar(barInst){}
};
This will do what you want it to. You store a pointer to a BarParent
object and you can polymorphicaly(is that a word?) call virtual functions using it.
You need to create the copy outside the constructor (on the heap or otherwise), and pass the pointer to it to the foo
object constructor. Alternatively you can implement a clone method as discussed at Copying derived entities using only base class pointers, (without exhaustive testing!) - C++
A radically different approach would be to use templates.. it would leave you with a multidudes of foo<>
types though.. If you are not going to reassign the bar
object, or store all foo
in a container, this might be the better option for you, since it doesn't involve the heap
template<typename BarType>
class Foo
{
BarType bar; //pointer not needed any more since we are storing the exact type.
public:
Foo(BarType& barInst):bar(barInst){}
};
Upvotes: 2
Reputation: 409176
There is no way I know of to handle this gracefully without object slicing.
The only way I could think of would be to use pointer, and create a copy when "calling" the Foo
constructor:
class Foo
{
BarParent* bar;
public:
Foo(BarParent* b) : bar(b) {}
};
BarChild child;
Foo myFoo(new BarChild(child));
Upvotes: 0