typeid (). name () Gets the type name

Turn: https://blog.csdn.net/TuxedoLinux/article/details/80604377

c ++ kind of mechanism is called RTTI (Run-Time Type Identification, runtime type identification), which enables programs acquired by the base pointer or reference practical derived type of the object pointed to, which allows "a pointer to the base class or reference to operation target "program can obtain the" pointer or reference to these referents "actually derived types. In C ++, RTTI provided to support two operators: dynamic_cast and typeid. dynamic_cast allows runtime type conversion, so that the program can be in a class hierarchy safely conversion type, with the corresponding non-secure and a conversion operator static_cast, typeid keyword is one of C ++, is equivalent to sizeof operator of such. Typeid operator returns the result is called an object library types of type_info of reference (as defined in the header file typeinfo later and we look vs gcc library inside the source code), it has two forms of expression under the map

  If the type of the expression is a class type and comprises at least one virtual function, the operator returns expression typeid dynamic type, needs to be calculated at run time; otherwise, typeid operator returns the static type of the expression, at compile time can calculation.
    ISO C ++ standard does not define the exact type_info, its exact definition of the compiler-related, but the standard stipulates that its implementation must provide the following four operations (in later chapters I will analyze source code type_info class files):

 t1 == t2  If the same type of two objects t1 and t2, return true; false otherwise
 t1! = t2  If two different types of objects t1 and t2, return true; false otherwise
 t.name()  Returns the type of C-style string, the method type name associated with the system produces
 t1.before(t2)  He pointed out that the return value bool appears before t1 and t2

  type_info class provides public virtual destructor, so that users can use it as a base class. And its default constructor is a copy constructor and assignment operator are defined as private, so can not be defined or copy objects type_info type. The only way to create an object type_info procedure is to use the typeid operator (Thus, if the typeid seen as a function, then it should be type_info's friend). member function returns the name type_info C-style string that represents a corresponding type name, it is important to note that the type of the corresponding name and type name used in the program returns not necessarily the same (often the case, see the following program) , which is determined by the specific compiler implementation, the standard required to achieve only returns a unique string for each type.

The following legend to show through the code and

#include <iostream>
using namespace std;

class Base {};
class Derived: public Base {};

int main()
{
    Base b, *pb;
    pb = NULL;
    Derived d;

    cout << typeid(int).name() << endl
         << typeid(unsigned).name() << endl
         << typeid(long).name() << endl
         << typeid(unsigned long).name() << endl
         << typeid(char).name() << endl
         << typeid(unsigned char).name() << endl
         << typeid(float).name() << endl
         << typeid(double).name() << endl
         << typeid(string).name() << endl
         << typeid(Base).name() << endl
         << typeid(b).name()<<endl
         << typeid(pb).name()<<endl
         << typeid(Derived).name() << endl
         << typeid(d).name()<<endl
         << typeid(type_info).name() << endl;
         
    return 0;
}

  I V8 and the MS respectively GUN This code GCC compiler and run, the results are below about two in FIG.

Next, add a little bit above the code content, as follows:

Base *pb2 = dynamic_cast<Base *>(new Derived);
Base &b2 = d;
Base *pb3 = &d;
cout << typeid(pb2).name() <<endl//输出Base *
     << typeid(b2).name()<<endl //输出Base
     << typeid(pb3).name()<<endl//输出Base *
     << typeid(*pb3).name()<<endl;//输出Base

因为Base不包含虚函数,所以typeid的结果指出,表达式的类型是Base或Base *型,尽管他们的底层对象是Derived。即:当typeid操作符的操作数是不带有虚函数的类类型时,typeid操作符会指出操作数的类型,而不是底层对象的类型。
    下面在对Base函数做一个小小调整,为其加上一个虚函数,再看输出结果。

class Base {virtual void f(){}; };
/*...*/
cout << typeid(pb2).name() <<endl//输出Base *
     << typeid(b2).name()<<endl //输出Derived
     << typeid(pb3).name()<<endl//输出Base *
     << typeid(*pb3).name()<<endl;//输出Derived

 这次Base含有虚函数,注意看结果,指针仍然是Base*的,尽管他们指向的是底层对象Derived,而这些Base对象的类型却是Derived的。
    因为指针pb3不是类类型,所以typeid就返回该指针pb3的指针类型Base *。而*pb3是一个类类型的表达式,而且该类带有虚函数,所以指出该pb3指向的底层对象的类型Derived。
    如果typeid操作符的操作数是至少包含一个虚拟函数的类类型时,并且该表达式是一个基类的引用,则typeid操作符指出底层对象的派生类类型。

 

Guess you like

Origin www.cnblogs.com/kerngeeksund/p/11204772.html