午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

C++中子類轉(zhuǎn)父類和父類轉(zhuǎn)子類的方法

 sofes 2017-08-22

18.2. Run-Time Type Identification

18.2. 運(yùn)行時(shí)類型識(shí)別

Run-time Type Identification (RTTI) allows programs that use pointers or references to base classes to retrieve the actual derived types of the objects to which these pointers or references refer.

通過運(yùn)行時(shí)類型識(shí)別(RTTI),程序能夠使用基類的指針或引用來檢索這些指針或引用所指對(duì)象的實(shí)際派生類型。

RTTI is provided through two operators:

通過下面兩個(gè)操作符提供 RTTI:

  1. The typeid operator, which returns the actual type of the object referred to by a pointer or a reference

    typeid 操作符,返回指針或引用所指對(duì)象的實(shí)際類型。

  2. The dynamic_cast operator, which safely converts from a pointer or reference to a base type to a pointer or reference to a derived type

    dynamic_cast 操作符,將基類類型的指針或引用安全地轉(zhuǎn)換為派生類型的指針或引用。

These operators return dynamic type information only for classes with one or more virtual functions. For all other types, information for the static (i.e., compile-time) type is returned.

這些操作符只為帶有一個(gè)或多個(gè)虛函數(shù)的類返回動(dòng)態(tài)類型信息,對(duì)于其他類型,返回靜態(tài)(即編譯時(shí))類型的信息。



The RTTI operators execute at run time for classes with virtual functions, but are evaluated at compile time for all other types.

對(duì)于帶虛函數(shù)的類,在運(yùn)行時(shí)執(zhí)行 RTTI 操作符,但對(duì)于其他類型,在編譯時(shí)計(jì)算 RTTI 操作符。

Dynamic casts are needed when we have a reference or pointer to a base class but need to perform operations from the derived class that are not part of the base class. Ordinarily, the best way to get derived behavior from a pointer to base is to do so through a virtual function. When we use virtual functions, the compiler automatically selects the right function according to the actual type of the object.

當(dāng)具有基類的引用或指針,但需要執(zhí)行不是基類組成部分的派生類操作的時(shí)候,需要?jiǎng)討B(tài)的強(qiáng)制類型轉(zhuǎn)換。通常,從基類指針獲得派生類行為最好的方法是通過虛函數(shù)。當(dāng)使用虛函數(shù)的時(shí)候,編譯器自動(dòng)根據(jù)對(duì)象的實(shí)際類型選擇正確的函數(shù)。

In some situations however, the use of virtual functions is not possible. In these cases, RTTI offers an alternate mechanism. However, this mechanism is more error-prone than using virtual member functions: The programmer mustknow to which type the object should be cast and must check that the cast was performed successfully.

但是,在某些情況下,不可能使用虛函數(shù)。在這些情況下,RTTI 提供了可選的機(jī)制。然而,這種機(jī)制比使用虛函數(shù)更容易出錯(cuò):程序員必須知道應(yīng)該將對(duì)象強(qiáng)制轉(zhuǎn)換為哪種類型,并且必須檢查轉(zhuǎn)換是否成功執(zhí)行了。

 

Dynamic casts should be used with caution. Whenever possible, it is much better to define and use a virtual function rather than to take over managing the types directly.

使用動(dòng)態(tài)強(qiáng)制類型轉(zhuǎn)換要小心。只要有可能,定義和使用虛函數(shù)比直接接管類型管理好得多。



18.2.1. The dynamic_cast Operator

18.2.1. dynamic_cast 操作符

The dynamic_cast operator can be used to convert a reference or pointer to an object of base type to a reference or pointer to another type in the same hierarchy. The pointer used with a dynamic_cast must be validit must either be0 or point to an object.

可以使用 dynamic_cast 操作符將基類類型對(duì)象的引用或指針轉(zhuǎn)換為同一繼承層次中其他類型的引用或指針。與dynamic_cast 一起使用的指針必須是有效的——它必須為 0 或者指向一個(gè)對(duì)象。

Unlike other casts, a dynamic_cast involves a run-time type check. If the object bound to the reference or pointer is not an object of the target type, then thedynamic_cast fails. If a dynamic_cast to a pointer type fails, the result of thedynamic_cast is the value 0. If a dynamic_cast to a reference type fails, then an exception of typebad_cast is thrown.

與其他強(qiáng)制類型轉(zhuǎn)換不同,dynamic_cast 涉及運(yùn)行時(shí)類型檢查。如果綁定到引用或指針的對(duì)象不是目標(biāo)類型的對(duì)象,則dynamic_cast 失敗。如果轉(zhuǎn)換到指針類型的 dynamic_cast 失敗,則 dynamic_cast 的結(jié)果是 0 值;如果轉(zhuǎn)換到引用類型的dynamic_cast 失敗,則拋出一個(gè) bad_cast 類型的異常。

The dynamic_cast operator therefore performs two operations at once. It begins by verifying that the requested cast is valid. Only if the cast is valid does the operator actually do the cast. In general, the type of the object to which the reference or pointer is bound isn't known at compile-time. A pointer to base can be assigned to point to a derived object. Similarly, a reference to base can be initialized by a derived object. As a result, the verification that thedynamic_cast operator performs must be done at run time.

因此,dynamic_cast 操作符一次執(zhí)行兩個(gè)操作。它首先驗(yàn)證被請(qǐng)求的轉(zhuǎn)換是否有效,只有轉(zhuǎn)換有效,操作符才實(shí)際進(jìn)行轉(zhuǎn)換。一般而言,引用或指針?biāo)壎ǖ膶?duì)象的類型在編譯時(shí)是未知的,基類的指針可以賦值為指向派生類對(duì)象,同樣,基類的引用也可以用派生類對(duì)象初始化,因此,dynamic_cast 操作符執(zhí)行的驗(yàn)證必須在運(yùn)行時(shí)進(jìn)行。

Using the dynamic_cast Operator
使用 dynamic_cast 操作符

As a simple example, assume that Base is a class with at least one virtual function and that classDerived is derived from Base. If we have a pointer to Base namedbasePtr, we can cast it at run time to a pointer to Derived as follows:

作為例子,假定 Base 是至少帶一個(gè)虛函數(shù)的類,并且 Derived 類派生于 Base 類。如果有一個(gè)名為 basePtr 的指向 Base 的指針,就可以像這樣在運(yùn)行時(shí)將它強(qiáng)制轉(zhuǎn)換為指向 Derived 的指針:

     if (Derived *derivedPtr = dynamic_cast<Derived*>(basePtr))
     {
         // use the Derived object to which derivedPtr points
     } else { // BasePtr points at a Base object
         // use the Base object to which basePtr points
     }

At run time, if basePtr actually points to a Derived object, then the cast will be successful, andderivedPtr will be initialized to point to the Derived object to whichbasePtr points. Otherwise, the result of the cast is 0, meaning that derivedPtr is set to 0, and the condition in the if fails.

在運(yùn)行時(shí),如果 basePtr 實(shí)際指向 Derived 對(duì)象,則轉(zhuǎn)換將成功,并且 derivedPtr 將被初始化為指向 basePtr 所指的 Derived 對(duì)象;否則,轉(zhuǎn)換的結(jié)果是 0,意味著將derivedPtr 置為 0,并且 if 中的條件失敗。

 

We can apply a dynamic_cast to a pointer whose value is 0. The result of doing so is 0.

可以對(duì)值為 0 的指針應(yīng)用 dynamic_cast,這樣做的結(jié)果是 0。



By checking the value of derivedPtr, the code inside theif knows that it is operating on a Derived object. It is safe for that code to useDerived operations. If the dynamic_cast fails because basePtr refers to aBase object, then the else clause does processing appropriate toBase instead. The other advantage of doing the check inside the if condition is that it is not possible to insert code between thedynamic_cast and testing the result of the cast. It is, therefore, not possible to use thederivedPtr inadvertently before testing that the cast was successful. A third advantage is that the pointer is not accessible outside theif. If the cast fails, then the unbound pointer is not available for use in later cases where the test might be forgotten.

通過檢查 derivedPtr 的值,if 內(nèi)部的代碼知道它是在操作 Derived 對(duì)象,該代碼使用Derived 的操作是安全的。如果 dynamic_castbasePtr 引用了 Base 對(duì)象而失敗,則else 子句進(jìn)行適應(yīng)于 Base 的處理來代替。在 if 條件內(nèi)部進(jìn)行檢查的另一好處是,不可能在 dynamic_cast測(cè)試轉(zhuǎn)換結(jié)果之間插入代碼,因此,不可能在測(cè)試轉(zhuǎn)換是否成功之前不經(jīng)意地使用 derivedPtr。第三個(gè)好處是,在if 外部不能訪問該指針,如果轉(zhuǎn)換失敗,則在后面的忘了測(cè)試的地方,未綁定的指針是不可用的。

 

Performing a dynamic_cast in a condition ensures that the cast and test of its result are done in a single expression.

在條件中執(zhí)行 dynamic_cast 保證了轉(zhuǎn)換和其結(jié)果測(cè)試在一個(gè)表達(dá)式中進(jìn)行。



Using a dynamic_cast and Reference Types
使用 dynamic_cast 和引用類型

In the previous example, we used a dynamic_cast to convert a pointer to base to a pointer to derived. Adynamic_cast can also be used to convert a reference to base to a reference to derived. The form for this adynamic_cast operation is the following,

在前面例子中,使用了 dynamic_cast 將基類指針轉(zhuǎn)換為派生類指針,也可以使用 dynamic_cast 將基類引用轉(zhuǎn)換為派生類引用,這種dynamic_cast 操作的形式如下:

     dynamic_cast< Type& >(val)

where Type is the target type of the conversion, and val is an object of base class type.

這里,Type 是轉(zhuǎn)換的目標(biāo)類型,而 val 是基類類型的對(duì)象。

The dynamic_cast operation converts the operand val to the desired typeType& only if val actually refers to an object of the type Type or is an object of a type derived from Type.

只有當(dāng) val 實(shí)際引用一個(gè) Type 類型對(duì)象,或者 val 是一個(gè)Type 派生類型的對(duì)象的時(shí)候,dynamic_cast 操作才將操作數(shù) val 轉(zhuǎn)換為想要的 Type& 類型。

Because there is no such thing as a null reference, it is not possible to use the same checking strategy for references that is used for pointer casts. Instead, when a cast fails, it throws astd::bad_cast exception. This exception is defined in the typeinfo library header.

因?yàn)椴淮嬖诳找?,所以不可能?duì)引用使用用于指針強(qiáng)制類型轉(zhuǎn)換的檢查策略,相反,當(dāng)轉(zhuǎn)換失敗的時(shí)候,它拋出一個(gè) std::bad_cast 異常,該異常在庫頭文件typeinfo 中定義。

We might rewrite the previous example to use references as follows:

可以重寫前面的例子如下,以便使用引用:

     void f(const Base &b)
     {
        try {
            const Derived &d = dynamic_cast<const Derived&>(b);
        // use the Derived object to which b referred
        } catch (bad_cast) {
            // handle the fact that the cast failed
        }
     }


18.2.2. The typeid Operator

18.2.2. typeid 操作符

The second operator provided for RTTI is the typeid operator. Thetypeid operator allows a program to ask of an expression: What type are you?

為 RTTI 提供的第二個(gè)操作符是 typeid 操作符。typeid 操作符使程序能夠問一個(gè)表達(dá)式:你是什么類型?

A typeid expression has the form

typeid 表達(dá)式形如:

     typeid(e)

where e is any expression or a type name.

這里 e 是任意表達(dá)式或者是類型名。

If the type of the expression is a class type and that class contains one or more virtual functions, then the dynamic type of the expression may differ from its static compile-time type. For example, if the expression dereferences a pointer to a base class, then the static compile-time type of that expression is the base type. However, if the pointer actually addresses a derived object, then thetypeid operator will say that the type of the expression is the derived type.

如果表達(dá)式的類型是類類型且該類包含一個(gè)或多個(gè)虛函數(shù),則表達(dá)式的動(dòng)態(tài)類型可能不同于它的靜態(tài)編譯時(shí)類型。例如,如果表達(dá)式對(duì)基類指針解引用,則該表達(dá)式的靜態(tài)編譯時(shí)類型是基類類型;但是,如果指針實(shí)際指向派生類對(duì)象,則typeid 操作符將說表達(dá)式的類型是派生類型。

The typeid operator can be used with expressions of any type. Expressions of built-in type as well as constants can be used as operands for thetypeid operator. When the operand is not of class type or is a class without virtual functions, then thetypeid operator indicates the static type of the operand. When the operand has a class-type that defines at least one virtual function, then the type is evaluated at run time.

typeid 操作符可以與任何類型的表達(dá)式一起使用。內(nèi)置類型的表達(dá)式以及常量都可以用作 typeid 操作符的操作數(shù)。如果操作數(shù)不是類類型或者是沒有虛函數(shù)的類,則typeid 操作符指出操作數(shù)的靜態(tài)類型;如果操作數(shù)是定義了至少一個(gè)虛函數(shù)的類類型,則在運(yùn)行時(shí)計(jì)算類型。

The result of a typeid operation is a reference to an object of a library type namedtype_info. Section 18.2.4 (p. 779) covers this type in more detail. To use the type_info class, the library headertypeinfo must be included.

typeid 操作符的結(jié)果是名為 type_info 的標(biāo)準(zhǔn)庫類型的對(duì)象引用,第 18.2.4 節(jié)將更詳細(xì)地討論這個(gè)類型。要使用type_info 類,必須包含庫頭文件 typeinfo。

Using the typeid Operator
使用 typeid 操作符

The most common use of typeid is to compare the types of two expressions or to compare the type of an expression to a specified type:

typeid 最常見的用途是比較兩個(gè)表達(dá)式的類型,或者將表達(dá)式的類型與特定類型相比較:

     Base *bp;
     Derived *dp;
     // compare type at run time of two objects
     if (typeid(*bp) == typeid(*dp)) {
         // bp and dp point to objects of the same type
     }
     // test whether run time type is a specific type
     if (typeid(*bp) == typeid(Derived)) {
         // bp actually points to a Derived
     }

In the first if, we compare the actual types of the objects to whichbp and dp point. If they both point to the same type, then the test succeeds. Similarly, the secondif succeeds if bp currently points to a Derived object.

第一個(gè) if 中,比較 bp 所指對(duì)象與 dp 所指對(duì)象的實(shí)際類型,如果它們指向同一類型,則測(cè)試成功。類似地,如果bp 當(dāng)前指向 Derived 對(duì)象,則第二個(gè) if 成功。

Note that the operands to the typeid are expressions that are objectswe tested*bp, not bp:

注意,typeid 的操作數(shù)是表示對(duì)象的表達(dá)式——測(cè)試 *bp,而不是 bp

     // test always fails: The type of bp is pointer to Base
     if (typeid(bp) == typeid(Derived)) {
          // code never executed
     }

This test compares the type Base* to type Derived. These types are unequal, so this test will always failregardless of the type of the object to which bp points.

這個(gè)測(cè)試將 Base* 類型與 Derived 類型相比較,這兩個(gè)類型不相等,所以,無論bp 所指對(duì)象的類型是什么,這個(gè)測(cè)試將問題失敗。

 

Dynamic type information is returned only if the operand to typeid is an object of a class type with virtual functions. Testing a pointer (as opposed to the object to which the pointer points) returns the static, compile-time type of the pointer.

只有當(dāng) typeid 的操作數(shù)是帶虛函數(shù)的類類型的對(duì)象的時(shí)候,才返回動(dòng)態(tài)類型信息。測(cè)試指針(相對(duì)于指針指向的對(duì)象)返回指針的靜態(tài)的、編譯時(shí)類型。



If the value of a pointer p is 0, then typeid(*p) throws abad_typeid exception if the type of p is a type with virtual functions. If the type ofp does not define any virtuals, then the value of p is irrelevant. As when evaluating asizeof expression (Section 5.8, p. 167) the compiler does not evaluate *p. It uses the static type of p, which does not require that p itself be a valid pointer.

如果指針 p 的值是 0,那么,如果 p 的類型是帶虛函數(shù)的類型,則 typeid(*p) 拋出一個(gè)bad_typeid 異常;如果 p 的類型沒有定義任何虛函數(shù),則結(jié)果與 p 的值是不相關(guān)的。正像計(jì)算表達(dá)式sizeof第 5.8 節(jié))一樣,編譯器不計(jì)算 *p,它使用 p 的靜態(tài)類型,這并不要求 p 本身是有效指針。


18.2.3. Using RTTI

18.2.3. RTTI 的使用

As an example of when RTTI might be useful, consider a class hierarchy for which we'd like to implement the equality operator. Two objects are equal if they have the same value for a given set of their data members. Each derived type may add its own data, which we will want to include when testing for equality.

作為說明何時(shí)可以使用 RTTI 的例子,考慮一個(gè)類層次,我們希望為它實(shí)現(xiàn)相等操作符。如果兩個(gè)對(duì)象的給定數(shù)據(jù)成員集合的值相同,它們就相等。每個(gè)派生類型可以增加自己的數(shù)據(jù),我們希望在測(cè)試相等的時(shí)候包含這些數(shù)據(jù)。

Because the values considered in determining equality for a derived type might differ from those considered for the base type, we'll (potentially) need a different equality operator for each pair of types in the hierarchy. Moreover, we'd like to be able to use a given type as either the left-hand or right-hand operand, so we'll actually need two operators for each pair of types.

因?yàn)榇_定派生類型的相等與確定基類類型的相等所考慮的值不同,所以對(duì)層次中的每一對(duì)類型(潛在地)需要一個(gè)不同的相等操作符。而且,希望能夠使用給類型作為左操作數(shù)或右操作數(shù),所以實(shí)際上對(duì)每一對(duì)類型將需要兩個(gè)操作符。

If our hierarchy has only two types, we need four functions:

如果類層次中只有兩個(gè)類型,就需要四個(gè)函數(shù):

     bool operator==(const Base&, const Base&)
     bool operator==(const Derived&, const Derived&)
     bool operator==(const Derived&, const Base&);
     bool operator==(const Base&, const Derived&);

But if our hierarchy has several types, the number of operators we must define expands rapidlyfor only 3 types we'd need 9 operators. If the hierarchy has 4 types, we'd need 16, and so on.

但是,如果類層次中有幾個(gè)類型,必須定義的操作符的數(shù)目就迅速擴(kuò)大——僅僅 3 個(gè)類型就需要 9 個(gè)操作符。如果類層次有 4 個(gè)類型,將需要 16 個(gè)操作符,以此類推。

We might think we could solve this problem by defining a set of virtual functions that would perform the equality test at each level in the hierarchy. Given those virtuals, we could define a single equality operator that operates on references to the base type. That operator could delegate its work to a virtual equal operation that would do the real work.

也許我們認(rèn)為可以通過定義一個(gè)虛函數(shù)集合來解決這個(gè)問題,這些虛函數(shù)可以在類層次中每一層執(zhí)行相等測(cè)試。給定這些虛函數(shù),可以定義單個(gè)相等操作符,操作基類類型的引用,該操作符可以將工作委派給可以完成實(shí)際工作的虛操作。

Unfortunately, virtual functions are not a good match to this problem. The trouble is deciding on the type for the parameter to theequal operation. Virtual functions must have the same parameter type(s) in both the base and derived classes. That implies that a virtualequal operation must have a parameter that is a reference to the base class.

但是,虛函數(shù)并不是解決這個(gè)問題的好辦法。麻煩在于決定 equal 操作的形參的類型。虛函數(shù)在基類類型和派生類型中必須有相同的形參類型,這意味著,虛equal 操作必須有一個(gè)形參是基類的引用。

However, when we compare two derived objects, we want to compare data members that might be particular to that derived class. If the parameter is a reference to base, we can use only members that are present in the base class. We cannot access members that are in the derived class but not in the base.

但是,當(dāng)比較兩個(gè)派生類對(duì)象的時(shí)候,我們希望比較可能特定于派生類的數(shù)據(jù)成員。如果形參是基類的引用,就只能比較基類中出現(xiàn)的成員,我們不能訪問在派生類中但不在基類中出現(xiàn)的成員。

Thinking about the problem in this detail, we see that we want to return false if we attempt to compare objects of different types. Given this observation, we can now use RTTI to solve our problem.

仔細(xì)考慮這個(gè)問題,我們看到,希望在試圖比較不同類型的對(duì)象時(shí)返回假(false)。有了這個(gè)觀察,現(xiàn)在可以使用 RTTI 解決我們的問題。

We'll define a single equality operator. Each class will define a virtualequal function that first casts its operand to the right type. If the cast succeeds, then the real comparison will be performed. If the cast fails, then theequal operation will return false.

我們將定義單個(gè)相等操作符。每個(gè)類定義一個(gè)虛函數(shù) equal,該函數(shù)首先將操作數(shù)強(qiáng)制轉(zhuǎn)換為正確的類型。如果轉(zhuǎn)換成功,就進(jìn)行真正的比較;如果轉(zhuǎn)換失敗,equal 操作就返回false。

The Class Hierarchy
類層次

To make the concept a bit more concrete, let's assume that our classes look something like:

為了使概念更清楚一點(diǎn),假定類層次是這樣的:

     class Base {
         friend bool operator==(const Base&, const Base&);
     public:
         // interface members for Base
     protected:
         virtual bool equal(const Base&) const;
         // data and other implementation members of Base
     };
     class Derived: public Base {
         friend bool operator==(const Base&, const Base&);
     public:
         // other interface members for Derived
     private:
         bool equal(const Base&) const;
         // data and other implementation members of Derived
     };

A Type-Sensitive Equality Operator
類型敏感的相等操作符

Next let's look at how we might define the overall equality operator:

下面看看可以怎樣定義整體的相等操作符:

     bool operator==(const Base &lhs, const Base &rhs)
     {
        // returns false if typeids are different otherwise
        // returns lhs.equal(rhs)
        return typeid(lhs) == typeid(rhs) && lhs.equal(rhs);
     }

This operator returns false if the operands are different types. If they are the same type, then it delegates the real work of comparing the operands to the appropriate virtualequal function. If the operands are Base objects, then Base::equal will be called. If they areDerived objects, Derived::equal is called.

如果操作數(shù)類型不同,這個(gè)操作符就返回假;如果操作數(shù)類型相同,它就將實(shí)際比較操作數(shù)的工作委派給適當(dāng)?shù)奶摵瘮?shù) equal。如果操作數(shù)是Base 對(duì)象,就調(diào)用 Base::equal;如果操作數(shù)是 Derived 對(duì)象,就調(diào)用 Derived::equal。

The Virtual equal Functions
虛函數(shù) equal

Each class in the hierarchy must define its own version of equal. The functions in the derived classes will all start the same way: They'll cast their argument to the type of the class itself:

層次中的每個(gè)類都必須定義自己的 equal 版本。派生類中的 equal 函數(shù)將以相同的方式開始:它們將實(shí)參強(qiáng)制轉(zhuǎn)換為類本身的類型。

     bool Derived::equal(const Base &rhs) const
     {
        if (const Derived *dp
                   = dynamic_cast<const Derived*>(&rhs)) {
           // do work to compare two Derived objects and return result
        } else
           return false;
     }

The cast should always succeedafter all, the function is called from the equality operator only after testing that the two operands are the same type. However, the cast is necessary so that the function can access the derived members of the right-hand operand. The operand is a Base&, so if we want to access members of theDerived, we must first do the cast.

這個(gè)強(qiáng)制轉(zhuǎn)換應(yīng)該總是成功——畢竟,只有有測(cè)試了兩個(gè)操作數(shù)類型相同之后,才從相等操作符調(diào)用該函數(shù)。但是,這個(gè)強(qiáng)制轉(zhuǎn)換是必要的,以便函數(shù)可以訪問右操作數(shù)的派生類成員。因?yàn)椴僮鲾?shù)是Base&,所以如果想要訪問 Derived 的成員,就必須首先進(jìn)行強(qiáng)制轉(zhuǎn)換。

The Base-Class equal Function
基類 equal 函數(shù)

This operation is a bit simpler than the others:

這個(gè)操作比其他的簡(jiǎn)單一點(diǎn):

     bool Base::equal(const Base &rhs) const
     {
          // do whatever is required to compare to Base objects
     }

There is no need to cast the parameter before using it. Both *this and the parameter are Base objects, so all the operations available for this object are also defined for the parameter type.

使用形參之前不必強(qiáng)制轉(zhuǎn)換,*this 和形參都是 Base 對(duì)象,所以對(duì)形參類型也定義了該對(duì)象可用的所有操作。

18.2.4. The type_info Class

18.2.4. type_info

The exact definition of the type_info class varies by compiler, but the standard guarantees that all implementations will provide at least the operations listed inTable 18.2

type_info 類的確切定義隨編譯器而變化,但是,標(biāo)準(zhǔn)保證所有的實(shí)現(xiàn)將至少提供表 18.2 列出的操作。

Table 18.2. Operations on type_info
表 18.2. type_info 的操作

The class also provides a public virtual destructor, because it is intended to serve as a base class. If the compiler wants to provide additional type information, it should do so in a class derived fromtype_info.

因?yàn)榇蛩阕骰愂褂茫?tt>type_info 類也提供公用虛析構(gòu)函數(shù)。如果編譯器想要提供附加的類型信息,應(yīng)該在 type_info 的派生類中進(jìn)行。

The default and copy constructors and the assignment operator are all defined asprivate, so we cannot define or copy objects of type type_info. The only way to createtype_info objects in a program is to use the typeid operator.

默認(rèn)構(gòu)造函數(shù)和復(fù)制構(gòu)造函數(shù)以及賦值操作符都定義為 private,所以不能定義或復(fù)制 type_info 類型的對(duì)象。程序中創(chuàng)建type_info 對(duì)象的唯一方法是使用 typeid 操作符。

The name function returns a C-style character string for the name of the type represented by thetype_info object. The value used for a given type depends on the compiler and in particular is not required to match the type names as used in a program. The only guarantee we have about the return fromname is that it returns a unique string for each type. Nonetheless, the name member can be used to print the name of a type_info object:

name 函數(shù)為 type_info 對(duì)象所表示的類型的名字返回 C 風(fēng)格字符串。給定類型所用的值取決于編譯器,具體來說,無須與程序中使用的類型名字匹配。對(duì)name 返回值的唯一保證是,它為每個(gè)類型返回唯一的字符串。雖然如此,仍可以使用 name 成員來顯示 type_info 對(duì)象的名字:

     int iobj;
     cout << typeid(iobj).name() << endl
          << typeid(8.16).name() << endl
          << typeid(std::string).name() << endl
          << typeid(Base).name() << endl
          << typeid(Derived).name() << endl;

The format and value returned by name varies by compiler. This program, when executed on our machine, generates the following output:

name 返回的格式和值隨編譯器而變化。在我們的機(jī)器上執(zhí)行時(shí),這個(gè)程序產(chǎn)生下面的輸出:

     i
     d
     Ss
     4Base
     7Derived

 

The type_info class varies by compiler. Some compilers provide additional member functions that provide additional information about types used in a program. You should consult the reference manual for your compiler to understand the exact type_info support provided.

type_info 類隨編譯器而變。一些編譯器提供附加的成員函數(shù),那些函數(shù)提供關(guān)于程序中所用類型的附加信息。你應(yīng)該查閱編譯器的參考手冊(cè)來理解所提供的確切的type_info 支持。



    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多