我当时在学习http://www.justsoftwaresolutions.co.uk/articles/genericptr.pdf。我对第4节有些困惑。有一种说法是
仅当结果类型为多态类类型的lvalue时,才计算作为参数提供给type if运算符的表达式。
与此相关的示例代码是:
template<typename T>
void* startOfObject(T* p) {
void* q=static_cast<void*>(p);
typeid(q=dynamic_cast<void*>(p),*p); // This line
return q;
}这意味着如果结果类型是多态类类型的l值,则将对q=dynamic_cast<void*>(p)进行评估。结果意味着评估dynamic_cast<void*>(p)的结果(我猜),因此dynamic_cast必须在任何情况下应用。这些文章声明(据我理解),如果p不是多态的,那么dynamic_cast就不会被应用,但是为什么呢?在应用之前,如何知道结果是否是多态的?如果有人详细描述如何执行完整的语句,这将是有帮助的。
另一种说法是
如果p为NULL,还会出现一个问题--类型将抛出std::坏的强制转换。
我看到的问题是,如果p是NULL,则取消引用,而不是使用typeid (虽然它可能抛出bad_typeid,但这不是因为转换)。dynamic_cast将返回一个类型为void*的NULL指针,如果p是NULL,那么typeid应该能够推断类型信息。是打错了,还是我漏掉了什么?
发布于 2014-06-06 08:56:47
从本质上讲,编写以下代码是一种奇妙的技巧
if (T is polymorphic)
return dynamic_cast<void*>(p);
else
return static_cast<void*>(p);使用的诀窍是,typeid(expr)是通过两种方法中的一种进行评估的。如果编译器确定expr具有非多态类型,则继续使用它的静态类型。但是,如果expr具有动态类型,它将在运行时计算expr。因此,逗号运算符之前的赋值是计算当且仅当逗号后面的*p是多态的。
由于这个原因,空的情况很复杂。如果T不是多态的,那么typeid(*p)在编译时被编译器替换,运行时空指针根本不重要。如果T是多态的,则适用对空指针取消引用的特殊处理,并且该特殊处理声明抛出std::bad_typeid异常。
发布于 2014-06-06 08:40:15
逗号运算符具有从左到右的结合性,并从左到右求值.这意味着表达式q=dynamic_cast<void*>(p),*p的结果是*p。因此,只有在*p类型是多态的情况下,才会对动态强制转换进行评估。
关于NULL问题,标准声明:
当类型is应用于类型为多态类类型(10.3)的lvalue表达式时,结果引用一个type_info对象,该对象表示lvalue所引用的最派生对象(1.8) (即动态类型)的类型。如果通过将一元*运算符应用于指针获得lvalue表达式,且指针为空指针值(4.10),则typeid表达式将抛出bad_typeid异常(18.5.3).
https://stackoverflow.com/questions/24077253
复制相似问题