我一直在阅读dynamic_cast
上有关我正在研究的程序的教程,而且我还没有完全掌握如何利用它。
我有多个方法可以传递超类指针的参数,并从那里区分哪个方法来确定要进行哪些操作。
例如,超类可能是Value
,子类是RationalNumber
。
我的计划是为int
设置RationalNumber
值ID,我不知道,1,然后当我使用dynamic_cast
时,它将确定{ {1}}对象实际上是Value*
,将执行操作。
我如何实现这个目标?
答案 0 :(得分:2)
典型示例:
class Value
{
public:
virtual ~Value();
};
class RationalNumber : public Value
{
...
}
Value *v = new RationalNumber(...)
...
RationalNumber* test = dynamic_cast<RationalNumber*>(v);
if (v)
cout << "v is a rational number" << endl;
else
cout << "v is a not rational number" << endl;
但请注意,在几乎所有具有继承的情况下,这都不是一个好的解决方案。我正在编写一个编译器,这是我第一次使用dynamic_cast
- 主要是因为有一些相当通用的函数可以处理(例如){{1}类指针,并将所有派生类(当前计数的31个类)的函数的所有变量添加到ExprAST
中将是相当不实用的。 (当然,拨打ExprAST
的电话并不比expr->isVariableExprAST()
好得多 - 它的代码数量相同,或多或少。
但在大多数情况下,不知道你处理的是哪种类型是一个更好的解决方案。
更合适的解决方案是使用对所有类都通用的虚函数,例如:
VariableExprAST* var = dynamic_cast<VariableExprAST*>(expr); if (var) ...
在这种情况下,您不需要执行任何检查 - 您只需要为所有子类型实现方法class Value
{
public:
virtual ~Value();
virtual void SomeMethod() = 0;
};
class RationalNumber : public Value
{
...
virtual void SomeMethod() { ... }
}
class IrrationalNumber : public Value
{
...
virtual void SomeMethod() { ... }
}
Value *v = ...
v->SomeMethod();
。
答案 1 :(得分:2)
dynamic_cast
运算符根据对象的V-Table指针(当您有一个或多个时添加到对象类中的隐式成员字段)的值来确定运行时对象的类型该类中的虚函数。)
这里没有什么可以实现的,您可以简单地调用它。例如:
bool isRationalNumber(Value* object)
{
RationalNumber* number = dynamic_cast<RationalNumber*>(object);
if (number == NULL)
return false;
return true;
}
请注意,您不能在未声明至少一个虚拟函数的类上使用它,因为此类没有V-Table。
此外,在某些编译器上,您需要在项目设置中启用RTTI。
最后 - 一个小小的建议(更多的是个人观点,所以你可以选择忽略它):
动态强制转换与多态性概念形成鲜明对比,在多态性概念中,您可以在单个基类下概括具有公共属性的对象,然后使用泛型基类引用它们。使用动态强制转换,您实际上正好相反,因为您在决定要采取的操作之前检查对象的特定类型。
所以建议是,尽量避免使用它。
如果您发现自己没有其他选择,请检查您的设计。
答案 2 :(得分:0)
标准方法是dynamic_cast
派生类的对象,然后测试结果是否为null
。例如(使用您的术语):
void method(SuperClass* object) {
SubClass* subclass = dynamic_cast<SubClass*>(object);
if (subclass) {
// the object is a 'SubClass'
// do stuff...
}
}
如果您有多个子类,则必须单独检查它们。 E.g:
void method(SuperClass* object) {
SubClass_1* subclass_1 = dynamic_cast<SubClass_1*>(object);
if (subclass_1) {
// the object is a 'SubClass_1'
// do stuff...
return;
}
SubClass_2* subclass_2 = dynamic_cast<SubClass_2*>(object);
if (subclass_2) {
// the object is a 'SubClass_2'
// do stuff...
return;
}
}