在C++ 中使用dynamic_cast 的替代方案
我有这些课程:
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
首先,通过更改方法签名,您创建了一个隐藏基类的新方法。您需要让 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.
幸好它不起作用,因为 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.
与其为字段和验证器创建并行的类层次结构,您可能会更好地进行如下设计:
每个派生的验证器类都可以对什么是有效的、什么是无效的有不同的想法。
Rather than creating a parallel class hierarchy for fields and validators, you might be better off with a design something like this:
Each of your derived Validator classes can have different ideas of what is valid and what isn't.
您的代码充满了小错误。首先,您的类不会从任何东西派生,我假设
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 fromField
andDerivedValidator
fromValidator
. Second, you need to writevalidator->validate
, as it's a pointer. Third,Field::validate
has no argument but you callf->validate(v
). If these errors are corrected, then the only thing you got to do is makeValidator::validate
virtual and use your proposed solution (with thedynamic_cast
).您需要将 Validator::validate() 设为虚拟。
you need to make Validator::validate() virtual.