如何返回派生类型?

时间:2019-01-15 07:31:58

标签: c++ polymorphism

我有一个Validator类和从中派生的类; 当我试图返回指向派生类的指针时,方法将返回基类(Validator)而不是派生类。

class Validator
{
public:
    std::string m_name = "BaseValidator";

    static const std::map<std::string, Validator *> validators();

    static Validator *getByName(std::string &name);
};


const std::map<std::string, Validator*> Validator::validators()
{
    std::map<std::string, Validator*> result;
    //RequiredValidator is derived
    result["required"] = new RequiredValidator();
    return result;
}

Validator* Validator::getByName(std::string &name)
{
    auto g_validators = Validator::validators();
    auto validator = g_validators.find(name);
    if(validator != g_validators.end()){
        std::cout << "getByName: " << validator->second->m_name << std::endl;
        return validator->second;
    }else{
        std::cerr << "Unknow type of validator: " << name << std::endl;
    }
    return nullptr;
}

//output BaseValidator but i need RequiredValidator


class RequiredValidator : public Validator
{
public:
    std::string m_name = "RequiredValidator";
};

2 个答案:

答案 0 :(得分:2)

它正在返回派生实例,但是由于validatorValidator*,因此您正在查看m_name的{​​{1}}成员,而不是{{ 1}}。
(尽管名称相同,但它们是不同的变量。没有“虚拟变量”。)

有两种选择;

  • 您可以拥有一个虚拟的Validator函数,并在每个子类中覆盖它。

  • 在派生类中设置 base RequiredValidator,例如,通过将该名称作为基本构造函数的参数。

示例:

getName

答案 1 :(得分:1)

您已经声明了两个名为gradle的成员变量,一个在<input type="phone" numbers-only > 中,一个在m_name中。除了具有相同的名称之外,这两个变量是完全不相关的。您的编译器可能会在第二个阴影之前显示警告。

您访问哪个变量取决于您从中访问变量的类型。

例如:

Validator

有两种解决方案。第一种是简单地在RequiredValidator构造函数中设置RequiredValidator变量的值:

RequiredValidator r;
std::cout << r.m_name << "\n"; // prints "RequiredValidator"
Validator* v = &r;
std::cout << v->m_name << "\n"; // prints "BaseValidator"
std::cout << dynamic_cast<RequiredValidator*>(v)->m_name << "\n"; // prints "RequiredValidator"

更传统的解决方案是改为使用虚拟方法:

BaseValidator