RTTI、dynamic_cast、typeid、類與類之間的關係uml

1、RTTInode

Run-time type information (RTTI) is a mechanism that allows the type of an object to be determined during program execution.
ios

There are three main C++ language elements to run-time type information:express

  • The dynamic_cast operator. 編程

    Used for conversion of polymorphic types. 安全

  • The typeid operator. ide

    Used for identifying the exact type of an object.函數

  • The type_info class. spa

    Used to hold the type information returned by the typeid operator. orm


    class type_info {
    public:
    對象

        virtual ~type_info();
        bool operator==(const type_info& rhs) const;
        bool operator!=(const type_info& rhs) const;
        int before(const type_info& rhs) const;
        const char* name() const;
        const char* raw_name() const;
    private:
        void *_m_data;
        char _m_d_name[1];
        type_info(const type_info& rhs);
        type_info& operator=(const type_info& rhs);
        static const char _Name_base(const type_info *,__type_info_node* __ptype_info_node);
    };

    The result of typeid is a const type_info&. The value is a reference to a type_info object that represents either the type-id or the type of the expression, depending on which form of typeid is used. 


    爲了支持RTTI,爲每個多態類建立一個type_info 對象(靜態數據區),並把其地址保存到vtable中的固定位置(通常爲第一個位置)(取決於具體編譯器實現,標準並無規定)。

     C++ Code 
    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
     
    #include <iostream>
    using namespace std;

    class Shape
    {
    public:
        virtual void Draw() = 0;
        virtual ~Shape() {}
    };

    class Circle : public Shape
    {
    public:
        void Draw()
        {
            cout << "Circle Draw ..." << endl;
        }
    };

    class Square : public Shape
    {
    public:
        void Draw()
        {
            cout << "Square Draw ..." << endl;
        }
    };

    int main(void)
    {
        Shape *p;
        Circle c;

        p = &c;
        p->Draw();

        //使用dynamic_cast 的條件
        //一、開啓運行時類型信息;二、應用在具備多態關係的繼承體系上;
        if (dynamic_cast<Circle *>(p))
        {
            cout << "p is point to a Circle object" << endl;
            Circle *cp = dynamic_cast<Circle *>(p);     // 安全向下轉型
            cp->Draw(); //效率沒有 p->Draw(); 高
        }
        else if (dynamic_cast<Square *>(p))
        {
            cout << "p is point to a Square object" << endl;
        }
        else
        {
            cout << "p is point to a Other object" << endl;
        }

        cout << typeid(*p).name() << endl;
        cout << typeid(Circle).name() << endl;
        if (typeid(Circle).name() == typeid(*p).name())
        {
            cout << "p is point to a Circle object" << endl;
            ((Circle *)p)->Draw();
        }
        else if (typeid(Square).name() == typeid(*p).name())
        {
            cout << "p is point to a Circle object" << endl;
            ((Square *)p)->Draw();
        }
        else
        {
            cout << "p is point to a Other object" << endl;
        }

        return 0;
    }


    如上所述,dynamic_cast 和 typeid 操做符 均可以實現運行時類型識別。其中使用dynamic_cast 時須要開啓運行時類型信息,在項目-》屬性-》C/C++-》語言-》啓用運行時類型信息。在使用typeid時須要注意的是返回的是type_info 對象的引用,且type_info 類的拷貝構造函數和賦值運算符都聲明爲私有,故不能這樣寫: type_info tf = typeid(Circle);


    2、類與類之間的關係

    Unified Modeling Language (UML)又稱統一建模語言或標準建模語言,是始於1997年一個OMG標準,它是一個支持模型化和軟件系統開發的圖形化語言。

    一、繼承(泛化)Generalization


    Manager 繼承自Employee.


    二、關聯 Association,單向關聯 DirectedAssociation


    Order 做爲Customer 的成員,如vector<Order>  orders ;


    三、聚合 Aggregation

    class B

    class A

    public:
    B* b_;

    };

    當A釋放時,不負責B的釋放,也許B是被共享的。


    四、組合 Composition


    當Company 釋放時要負責Department 的釋放,Department 不是共享的。


    五、依賴 Dependency


    類A依賴於B:
    從語義上來上是A use B,偶然的,臨時的
    B做爲A的成員函數參數
    B做爲A的成員函數的局部變量
    A的成員函數調用B的靜態方法


    比較5種關係:

    繼承體現的是類與類之間的縱向關係,其餘4種體現的是類與類之間的橫向關係。
    關聯強弱

    依賴<關聯<聚合<組合
    繼承(A is B)
    關聯、聚合、組合(A has B)
    依賴(A use B)


參考:

C++ primer 第四版 Effective C++ 3rd C++編程規範

相關文章
相關標籤/搜索