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

Access derived virtual function from base class, good practice?

从基class访问派生虚函数是否有好的做法? 这是我到目前为止得到的:

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;
        }
    }
}

我不太喜欢在那里使用开关,如有任何建议,我们将不胜感激!

首先,显示的不是我所说的“从基地 class 呼叫”。除此以外, 从基 class 方法调用派生虚方法是使用虚函数的主要原因之一。另一个原因是通过指向基 class 的指针调用方法,就像您打算做的那样。

此外,如上所述,在:

bunch["01"] = B(10);

B 类型的临时对象静默转换(切片)到 classA 的对象。您应该使用指向 A 的指针映射。

您应该分配一个指针或引用以在 C++ 中使用多态性。如果您分配一个 child class 作为值,将会有一个 object 切片。我会使用 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;
}