Reputation: 12325
Is it possible to call a pure virtual function from a loop?
Some pseudocode to explain what im trying to achive
(tried a version of the following example but got error: object of abstract class type "Base" is not allowed)
class Base{
public:
virtual void printMe() =0;
};
class derivedOne{
public:
void printMe(){std::cout << "one "<<endl;
};
class derivedTwo{
public:
void printMe(){std::cout << "two"<<endl;
};
class holder{
private:
vector<derivedOne> one;
vector<derivedTwo> two;
void printDerive(vector<Base> bases){
for (Base base: bases)
{
base.printMe();
}
};
};
All derived classes implement the function printMe (because its a pure virtual function in base). Im trying to avoid writing a print loop for each class that implemented printMe from base because the functions will all do the same (loop the items in a vector and call printMe).
Upvotes: 1
Views: 232
Reputation: 65720
You can't have a vector<Base>
or have Base base
in your range-based for loop, because Base
is abstract and both of those require constructing a Base
.
One solution would be to store std::vector<std::unique_ptr<Base>>
for both one
and two
so that you can get dynamic dispatch:
class holder{
private:
std::vector<std::unique_ptr<Base>> one;
std::vector<std::unique_ptr<Base>> two;
public:
void printDerive(const std::vector<std::unique_ptr<Base>>& bases){
for (auto&& base: bases)
{
base->printMe();
}
};
};
Another option would be to keep your storage as-is and have a template function to print them:
class holder{
private:
std::vector<derivedOne> one;
std::vector<derivedTwo> two;
public:
template <class T>
void printDerive(const std::vector<T>& ts){
for (auto&& t: ts)
{
t.printMe();
}
};
};
These solutions will have consequences for how you allocate the elements and use the vectors, so choose based on your other requirements.
Upvotes: 3
Reputation: 10336
Your problem will be creating the vector<Base>
: this is not allowed, as it requires instantiation of an abstract class, Base
.
You could have a vector
of pointers to base, as it is only pointers (and references) that can behave polymorphically (note: your function should take the vector
by const
reference rather than by value):
void printDerive(const vector<std::unique_ptr<Base>>& bases){
for (auto& base: bases)
{
base->printMe();
}
};
Upvotes: 0