Reputation: 75
Is there a good practice to access a derived virtual function from it's base class? Here's what I got so far:
class A {
public:
enum class AType{A,B,C,D};
AType aType = AType::A;
virtual void Do(){}
};
class B : public A {
public:
int val = 0;
B(int i) {
aType = AType::B;
val = i;
}
void Do(){
std::cout << val << std::endl;
}
};
int main(){
std::map<std::string, A> bunch;
bunch["01"] = B(10);
bunch["02"] = B(15);
bunch["03"] = B(80);
for (auto& [k, b] : bunch){
switch (b.aType){
case A::AType::A:
break;
case A::AType::B:
static_cast<B&>(b).Do();
break;
}
}
}
I'm not too happy about using a switch there, any advice would be appreciated!
Upvotes: 0
Views: 110
Reputation: 1764
You should assign a pointer or reference to use polymorphism in C++. If you assign a child class as value, there would be a object slicing. I'd use std::unique_ptr
than raw pointer like following, which prints out 10 15 80
as excepted.
#include <memory>
#include <map>
class A {
public:
enum class AType { A, B, C, D };
AType aType = AType::A;
virtual void Do() {}
};
class B : public A {
public:
int val = 0;
B(int i) {
aType = AType::B;
val = i;
}
void Do() override {
std::cout << val << std::endl;
}
};
int main() {
std::map<std::string, std::unique_ptr<A>> bunch;
bunch["01"] = std::make_unique<B>(10);
bunch["02"] = std::make_unique<B>(15);
bunch["03"] = std::make_unique<B>(80);
for (auto& [k, b] : bunch) {
b->Do();
}
return 0;
}
Upvotes: 2
Reputation: 171
First, what're showing isn't what I'd call "calling from base class". Otherwise, calling derived virtual methods from a base class method is one of the main reasons to use virtual functions. The other reason is to call a method via pointer to base class, like you intend to do.
Also, as mentioned above, in:
bunch["01"] = B(10);
a temporary object of B type is silently cast (sliced) to object of class A. You should use perhaps map of pointers to A.
Upvotes: 1