I have Derived Classes that inherit from a Base class with virtual functions. Im using smart pointers(shared_ptr) in order to create the objects because i want the objects to be appended into a vector. But i noticed my code to be repetitive with handling to objects to do certain tasks so i thought a template could be solution to improve my code.
This is my attempt so far(not the exact code, simplified):
class Base{
public:
virtual ~Base(){}
virtual void display_message() = 0;
};
class DerivedA : public Base{
DerivedA(){}
};
class DerivedB : public Base{
DerivedB(){}
};
//THE template-
//<hold the smart pointer that points to different derived objects>
template<typename T1>
class HandleInstances{
private:
vector<T1> ObjectVector;
//the iterator
T1 sp_base;
public:
HandleInstance(const T1 & sp){
sp_base = sp; // set smart pointer
}
//somefunctions
//this is what i need to figure out
void AddToVector(){
ObjectVector.push_back(sp_base(new 'The derived class') );
}
};
The AddToVector functions is the problem here. in order to add an element of an object i have to do this push_back( “the smart pointer”( new “the class” ));. how do i let the template accept the class (not an object) and implement it to the function of push_back() ?
This is a challenging one – why? Because templates operate as a sort of preprocessing step in C++ by dynamically constructing variants of classes based on their template parameter.
In other words,
shared_ptr<DerivedA>andshared_ptr<DerivedB>have no relationship to each other whatsoever, because in C++, templates essentially make them like 2 separate class declarations – unrelated types.The pointers they contain are both descendants of the base class, but the shared_ptrs themselves might as well be a
Vector<Bool>and aFoo. It doesn’t matter thatDerivedAandDerivedBinherit from a single base class, their template-generated classes do not.That being said, you do have some flexibility: if you put a factory function in your classes’ interface, like this:
then you can do something like this:
and you should be OK. What you’re doing is giving each class a function to make up for the fact that the class itself can’t be stored to make objects later. Notice:
Constructis returning different types in DerivedA and DerivedB.Basehas no declaration ofconstruct– because these functions do not return compatible types, they are not inherited from Base.