Poylmorphim,构造函数-C 中使用的覆盖方法

Poylmorphism, overridden method used in constructor - C++

本文关键字:覆盖 方法 构造函数 Poylmorphim      更新时间:2023-10-16

我试图了解我的错误是来自设计问题还是代码错误。我的搜索指出了切片问题,但我认为这是这里的问题。

#include <string>
#include <iostream>
#include <vector>
    class BaseA {
    public:
        BaseA(const std::string &n)
            : name(n)
        {}
        virtual ~BaseA() 
        {};
        virtual void print() const
        {
            std::string str("");
            str += name;
            std::cout << str << std::endl;
        }
    protected:
        std::string name;
    };
    class BaseB : public BaseA {
    public:
        BaseB(const std::string &n, const std::string &v)
            : BaseA(n), value(v)
        { 
            load();
        }
        virtual ~BaseB() 
        {};
        virtual void load(){
             c = 'B';
        }
        char getC() {
            return c;
        }
        void print() const{
            std::string str("");
            str += name;
            str += ' ';
            str += value;
            std::cout << str << std::endl;
        }
    protected:
        char c;
    private:
        std::string value;
        int data = 0;
    };
    class BaseC : public BaseB {
    public:
        BaseC(const std::string &n, const std::string &v)
            : BaseB(n, v) 
        {
        }
        void load() override{
             c = 'C';
        }
    };
    int mainTest() 
    {
        std::vector<BaseB*> vec;
        vec.push_back(new BaseB("John", "singer"));
        vec.push_back(new BaseC("Raoul", "wannabe"));   
        for (BaseB *obj : vec)
        {
            obj->print();
            std::cout << "load class: " << obj->getC() << std::endl;
        }
        return(0);
    };

我希望结果是:

John singer 
load class: B 
Raoul wannabe 
load class: C

,但我都得到了B。这是否意味着在构造函数中,不可能使用覆盖的类?谢谢

这不是不可能的,但可能不会做您想要的。

回想一下,对于BaseC,施工顺序为BaseABaseBBaseC

BaseB构造(构造函数执行)时,即使是BaseC的对象,也没有作为BaseC构造的一部分构造的对象。

因此,标准要求在BaseB的构造函数(和驱动器)期间,调用load()将导致调用BaseB::load()。不是BaseC::load()