首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

typid() 是运行时实施还是编译时执行

2013-02-25 
typid() 是运行时执行还是编译时执行。我在vs2008里面测试发现,如果typeid()的参数是类型,那么它是在编译期

typid() 是运行时执行还是编译时执行。
我在vs2008里面测试发现,
如果typeid()的参数是类型,那么它是在编译期间执行的。
如果typeid()的参数是对象,不且不含虚函数,那么它也是在编译期间执行的。
如果typeid()的参数是对象,且含有虚函数,那么它仍然是在编译期间执行的。
如果typeid()的参数是对象的引用,且含有虚函数,那么它是运行时执行的。
如果typeid()的参数是对指向含虚函数对象的指针的解引用,那么也是运行时执行的。

我想知道,对于上面的规则,标准里是这样规定的,还是属于未定义行为。我翻了一下c++标准,没有找到答案。

我的测试程序如下



template<const type_info&>
void f()
{
    cout<<"Hello Word!"<<end;

}
class B{
virtual void f(){}
};
class D:public B {};
int main()
{
    int * pi;
    f<*pi>();     //可以通过编译
 
    B *p = new D     //B是基类,含有虚函数,D是B的子类
    D *q = new D

    f<p>()         //可以通过编译
    f<*p>();     //不能通过编译
    f<*q>();      //不能通过编译。

    f<D>();      //可以通过编译。

   D d;
   B &b=d;
   D &d2=d;

   f<d>();        //可以通过编译
   f<b>();       //不能通过编译
   f<d2>();      //不能通过编译

}


谢谢。
[解决办法]
首先,不可能是未定义行为。引起未定义行为的程序是错误的。
其次,LZ没翻仔细。
ISO C++03 5.2.8 Type identification
2 When typeid is applied to an lvalue expression whose type is a polymorphic class type (10.3), the result refers to a type_info object representing the type of the most derived object (1.8) (that is, the dynamic type) to which the lvalue refers. If the lvalue expression is obtained by applying the unary * operator to a pointer62) and the pointer is a null pointer value (4.10), the typeid expression throws the bad_typeid exception (18.5.3).
3 When typeid is applied to an expression other than an lvalue of a polymorphic class type, the result refers to a type_info object representing the static type of the expression. Lvalue-to-rvalue (4.1), array-to-pointer (4.2), and function-to-pointer (4.3) conversions are not applied to the expression. If the type of the expression is a class type, the class shall be completely-defined. The expression is not evaluated.
4 When typeid is applied to a type-id, the result refers to a type_info object representing the type of the type-id. If the type of the type-id is a reference type, the result of the typeid expression refers to a type_info object representing the referenced type. If the type of the type-id is a class type or a reference to a class type, the class shall be completely-defined. Types shall not be defined in the type-id.


62) If p is an expression of pointer type, then *p, (*p), *(p), ((*p)), *((p)), and so on all meet this requirement.
第三,LZ的测试程序整个是错的。

[解决办法]

引用:
首先,不可能是未定义行为。引起未定义行为的程序是错误的。
其次,LZ没翻仔细。
ISO C++03 5.2.8 Type identification
2 When typeid is applied to an lvalue expression whose type is a polymorphic class type (10.3), the result refers to a t……

++
说得好。

楼主是不是认为f<int>和f<1>是一样的?假定其中1是int类型的。
[解决办法]
引用:
我在vs2008里面测试发现,
如果typeid()的参数是类型,那么它是在编译期间执行的。
如果typeid()的参数是对象,不且不含虚函数,那么它也是在编译期间执行的。
如果typeid()的参

数是对象,且含有虚函数,那么它仍然是在编译期间执行的。
如果typeid()的参数是对象的引用,且含有虚函数,那么它是运行时执行的。
如果typeid()的参数是对指向含虚函数对象的指针的解引……

有点奇怪你怎么会有这样的疑问,你所列出的这些代码都是typeid十分正常的行为,多态性只有在引用和指针上才能表现出来,这是常识了吧,对象由于静态类型和动态类型是一样的,因此它无法表现出多态性,因此只有含有虚函数的引用和对含有虚函数的指针进行解引用才会表现出动态性
[解决办法]
引用:
引用:

谢谢4楼的解答。

问这个问题的原因是:
显然对于多态类型的对象,typeid()必须在运行时才能得到结果。
但对于其它对象,假如没有标准规定,那么typeid()可以在编译时就计算出结果,也可以在运行时再统一计算结果。这导致了3楼的程序的测试结果是依赖编译器的,换个编译器可能会测出另一个结果。

解决了上面的问题也就解决了下面的……

不会的,其它情况的静态类型和动态类型都是一样的,无论编译期还是运行期都会得出相同的结果,不属于依赖编译器的行为。

热点排行