使用RTTI(通过使用typeid和dynamic_cast)几乎被普遍认为是糟糕的编程实践.
类似地,定义一个所有派生必须通过虚函数返回的类型标记也被认为是不好的做法,例如:
enum Type {
DERIVED_1,
DERIVED_2
};
class Base {
virtual Type type() = 0;
};
class Derived1 : public Base {
Type type() override {
return DERIVED_1;
}
};
class Derived2 : public Base {
Type type() override {
return DERIVED_2;
}
};
Run Code Online (Sandbox Code Playgroud)
但是,有时我需要区分不同的派生类,比如当我有一个指针时Base可能是Derived1或者Derived2:
Base *b = new Derived2();
// Approach 1:
if (typeid(*b) == typeid(Derived1)) {
std::cout << "I have a Derived1.\n";
} else if (typeid(*b) == typeid(Derived2)) {
std::cout << "I have a Derived2.\n";
}
// Approach 2:
if (b->type() == DERIVED_1) {
std::cout << "I have a Derived1.\n";
} else if (b->type() == DERIVED_2) {
std::cout << "I have a Derived2.\n";
}
Run Code Online (Sandbox Code Playgroud)
人们说基于类型的决策树是不好的做法,但有时候这是必要的!
假设我正在编写编译器并需要决定是否可以将给定表达式分配给:
/* ... */
Expr* parseAssignment(Expr *left) {
// Is "left" a type of Expr that we can assign to?
if (typeid(*left) == typeid(VariableExpr)) {
// A VariableExpr can be assigned to, so continue pasrsing the expression
/* ... */
} else {
// Any other type of Expr cannot be assigned to, so throw an error
throw Error{"Invalid assignment target."};
}
}
Run Code Online (Sandbox Code Playgroud)
(假设Expr是基类,而VariableExpr是其中的派生类)
有没有其他方法可以实现这种不被视为不良做法的行为?或者在这种情况下RTTI /虚函数和类型标签是否正常?
| 归档时间: |
|
| 查看次数: |
59 次 |
| 最近记录: |