File: typeid.yo

package info (click to toggle)
c%2B%2B-annotations 7.2.0-1
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 11,484 kB
  • ctags: 2,902
  • sloc: cpp: 15,844; makefile: 2,997; ansic: 165; perl: 90; sh: 29
file content (133 lines) | stat: -rw-r--r-- 5,716 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
As with the ti(dynamic_cast<>()) operator, the ti(typeid) is usually applied
to base class objects, that are actually derived class objects. Similarly, the
base class should contain one or more virtual functions.

In order to use the tt(typeid) operator, source files must
    hi(#include <typeinfo>)
        verb(
    #include <typeinfo>
        )
    Actually, the tt(typeid) operator returns an object of type ti(type_info),
which may, e.g., be compared to other tt(type_info) objects.

    Different compilers may offer different implementations of the class
tt(type_info), but at the very least it must provide the following interface:
        verb(
    class type_info
    {
        public:
            virtual ~type_info();
            int operator==(type_info const &other) const;
            int operator!=(type_info const &other) const;
            bool before(type_info const &rhs) const
            char const *name() const;
        private:
            type_info(type_info const &other);
            type_info &operator=(type_info const &other);
    };
        )
    Note that this class has a i(private copy constructor) and overloaded
hi(private assignment operator) hi(copy constructor: private)
    hi(assignment operator: private) assignment operator. This prevents the
normal construction or assignment of a tt(type_info) object. Such tt(type_info)
objects are constructed and returned by the tt(typeid)
operator. Compilers, however, may choose to extend or elaborate the
tt(type_info) class and provide, e.g., lists of functions that can be called
with a certain class.

    If the tt(type_id) operator is given a base class reference (where the
base class contains at least one virtual function), it will indicate that the
type of its operand is the derived class. For example:
        verb(
    class Base;     // contains at least one virtual function
    class Derived: public Base;

    Derived d;
    Base    &br = d;

    cout << typeid(br).name() << endl;
        )
    In this example the tt(typeid) operator is given a base class reference.
It will print the text ``tt(Derived)'', being the i(class name) of the class
tt(br) actually refers to. If tt(Base) does not contain virtual functions, the
text ``tt(Base)'' would have been printed.

    The tt(typeid) operator can be used to determine the name of the actual
type of hi(expression: actual type) expressions, not just of class type
objects. For example:
        verb(
    cout << typeid(12).name() << endl;     // prints:  int
    cout << typeid(12.23).name() << endl;  // prints:  double
        )
    Note, however, that the above example is suggestive at most of the type
that is printed. It em(may) be tt(int) and tt(double), but this is not
necessarily the case. If portability is required, make sure no tests against
these static, built-in text-strings are required. Check out what your compiler
produces in case of doubt.

    Nota that in situations where the tt(typeid) operator is applied to
determine the type of a derived class, a base class em(reference)
        hi(typeid: argument)
    should be used as the argument of the tt(typeid) operator. Consider
the following example:
        verb(
    class Base;     // contains at least one virtual function
    class Derived: public Base;

    Base *bp = new Derived;     // base class pointer to derived object

    if (typeid(bp) == typeid(Derived *))    // 1: false
        ...
    if (typeid(bp) == typeid(Base *))       // 2: true
        ...
    if (typeid(bp) == typeid(Derived))      // 3: false
        ...
    if (typeid(bp) == typeid(Base))         // 4: false
        ...
    if (typeid(*bp) == typeid(Derived))     // 5: true
        ...
    if (typeid(*bp) == typeid(Base))        // 6: false
        ...

    Base &br = *bp;

    if (typeid(br) == typeid(Derived))      // 7: true
        ...
    if (typeid(br) == typeid(Base))         // 8: false
        ...
        )
    Here, tt((1)) returns tt(false) as a tt(Base *) is not a tt(Derived
*). tt((2)) returns tt(true), as the two pointer types are the same, tt((3))
and tt((4)) return tt(false) as pointers to objects are not the objects
themselves.

    On the other hand, if tt(*bp) is used in the above expressions, then
tt((1)) and tt((2)) return tt(false) as an object (or reference to an object)
is not a pointer to an object, whereas tt((5)) now returns tt(true): tt(*bp)
actually refers to a tt(Derived) class object, and tt(typeid(*bp)) will return
tt(typeid(Derived)).  A similar result is obtained if a base class reference
is used: tt(7) returning tt(true) and tt(8) returning tt(false).

    The tt(type_info::before(type_info const &rhs)) member can be used to
determine the emi(collating order) of classes that can be used for comparing
two types for equality.  The function returns a nonzero value if tt(*this)
precedes tt(rhs) in the collating order for types. When a derived class is
compared to its base class the comparison returns 0, otherwise a non-zero
value. E.g.:
        verb(
    cout << typeid(ifstream).before(typeid(istream)) << endl;   // not 0
    cout << typeid(istream).before(typeid(ifstream)) << endl;   // 0
        )
    With basic types the implementor may implement that a comparison of a
`wider' type with a `smaller' type returns non-0, and 0 otherwise:
        verb(
    cout << typeid(double).before(typeid(int)) << endl;   // not 1
    cout << typeid(int).before(typeid(double)) << endl;   // 0
        )
    When two equal types are compared, 0 is returned:
        verb(
    cout << typeid(ifstream).before(typeid(ifstream)) << endl;   // 0
        )

    When a tt(0)-pointer is passed to the tt(operator typeid) a ti(bad_typeid)
exception is thrown.