访问从基类派生的虚函数,好的做法?

问题描述

是否有从基类访问派生的虚函数的良好实践? 这是到目前为止我得到的:

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的指针映射。