在C++ 中使用dynamic_cast 的替代方案

发布于 2024-11-28 23:29:21 字数 1014 浏览 3 评论 0原文

我有这些课程:

class Field{
public:
    int X;

    void validate(){
        validator->validate(this);
    }

    void setValidator(Validator* v){
        validator = v;
    }

private:
    Validator* validator;
};

class DerivedField : public Field{
public:
    int Y;
}

class Validator {
public:
    virtual void validate(Field*); // do something with Field.X
};

class DerivedValidator : public Validator {
    virtual void validate(Field*); //do something with DerivedField.Y
};

我想这样做:

DerivedValidator* v = new DerivedValidator();
DerivedField* f = new DerivedFiled();
f->setValidator(v);

f->validate(); // Error, Validator::validate called instead of DerivedValidator::validate

既然它不起作用,我该怎么做才能避免这种情况:

class DerivedValidator{
    void validate(Field* f){
        DerivedField* dv = dynamic_cast<DerivedField*>(f);

        // do something with dv.Y
    }
};

谢谢。

编辑:好的,所有“错误”现在都已修复。

I have these classes:

class Field{
public:
    int X;

    void validate(){
        validator->validate(this);
    }

    void setValidator(Validator* v){
        validator = v;
    }

private:
    Validator* validator;
};

class DerivedField : public Field{
public:
    int Y;
}

class Validator {
public:
    virtual void validate(Field*); // do something with Field.X
};

class DerivedValidator : public Validator {
    virtual void validate(Field*); //do something with DerivedField.Y
};

I want to do this:

DerivedValidator* v = new DerivedValidator();
DerivedField* f = new DerivedFiled();
f->setValidator(v);

f->validate(); // Error, Validator::validate called instead of DerivedValidator::validate

Since It doesnt work, what can I do to avoid this:

class DerivedValidator{
    void validate(Field* f){
        DerivedField* dv = dynamic_cast<DerivedField*>(f);

        // do something with dv.Y
    }
};

Thank you.

Edit: Ok, all 'bugs' fixed now.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

逆蝶 2024-12-05 23:29:21

首先,通过更改方法签名,您创建了一个隐藏基类的新方法。您需要让 DerivedValidator 的 validate() 方法仅采用 Field* 参数。

然后,一旦将 virtual 关键字添加到方法中,当您传入 DerivedField 时,应该调用正确的方法。

您仍然无法访问 DerivedField 的继承值,因为您没有告诉基类有关派生类的任何信息。即,Field 了解有关 Validator 类型的所有信息,但不知道 DerivedValidator 是什么。无论您想在派生类中访问什么,都必须通过基类签名。

First, by changing the method signature, you've created a new method that will hide the base class's. You need to have DerivedValidator's validate() method take a Field* parameter only.

Then, once you've added the virtual keyword to your methods, when you pass a DerivedField in, the correct method should be called.

You still won't be able to access the inherited values of DerivedField as you haven't told the base class anything about the derived class. ie, Field knows all about Validator types, but has no clue what a DerivedValidator is. Whatever you want to access in the derived class has to go via the base class signature.

最舍不得你 2024-12-05 23:29:21

幸好它不起作用,因为 DerivedField 不是从 Field 继承的。如果你想破解,你可以使用 C 风格的强制转换。

It's good that it doesn't work, since DerivedField doesn't inherit from Field. If you want to hack, you can just use C-style casts.

温折酒 2024-12-05 23:29:21

与其为字段和验证器创建并行的类层次结构,您可能会更好地进行如下设计:

class Field{
   public:
   int X;

   virtual bool validate(Validator* v){
      return (v->isValid(X));
   }
}

class DerivedField : public Field{
   public:
   int Y;

   virtual bool validate(Validator* v){
      return (v->isValid(X) && v->isValid(Y));
   }
}

每个派生的验证器类都可以对什么是有效的、什么是无效的有不同的想法。

Rather than creating a parallel class hierarchy for fields and validators, you might be better off with a design something like this:

class Field{
   public:
   int X;

   virtual bool validate(Validator* v){
      return (v->isValid(X));
   }
}

class DerivedField : public Field{
   public:
   int Y;

   virtual bool validate(Validator* v){
      return (v->isValid(X) && v->isValid(Y));
   }
}

Each of your derived Validator classes can have different ideas of what is valid and what isn't.

旧时光的容颜 2024-12-05 23:29:21

您的代码充满了小错误。首先,您的类不会从任何东西派生,我假设 DerivedField 继承自 Field ,而 DerivedValidator 则继承自 Validator 。其次,您需要编写 validator->validate,因为它是一个指针。第三,Field::validate没有参数,但您调用f->validate(v)。如果这些错误得到纠正,那么您唯一要做的就是将 Validator::validate 设为虚拟并使用您建议的解决方案(使用 dynamic_cast)。

You code is full of small errors. First, your classes son't derive from anything, I assume DerivedField inherits from Field and DerivedValidator from Validator. Second, you need to write validator->validate, as it's a pointer. Third, Field::validate has no argument but you call f->validate(v). If these errors are corrected, then the only thing you got to do is make Validator::validate virtual and use your proposed solution (with the dynamic_cast).

漆黑的白昼 2024-12-05 23:29:21

您需要将 Validator::validate() 设为虚拟。

you need to make Validator::validate() virtual.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文