问题描述
是否有从基类访问派生的虚函数的良好实践? 这是到目前为止我得到的:
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;
}
}
}
我对在那里使用开关不太满意,任何建议将不胜感激!
解决方法
您应该分配一个指针或引用以在C ++中使用多态。如果将子类分配为值,则将进行对象切片。我会使用std::unique_ptr
而不是原始指针,如下所示,它会打印出10 15 80
作为例外。
#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;
}
,
首先,显示的不是我所谓的“从基类调用”。除此以外, 从基类方法调用派生的虚拟方法是使用虚拟函数的主要原因之一。另一个原因是像您打算的那样,通过指向基类的指针来调用方法。
此外,如上所述:
bunch["01"] = B(10);
将B类型的临时对象静默转换(切片)为类A的对象。您应该使用指向A的指针映射。