从零开始学C++之RTTI、dynamic_cast、typeid、类与类之间的关系uml
一、RTTI
Run-time type information (RTTI) is a mechanism that allows the type of an object to be determined during program execution.
 
 
There are three main C++ language elements to run-time type information:
- 
The dynamic_cast operator. Used for conversion of polymorphic types. 
- 
The typeid operator. Used for identifying the exact type of an object. 
- 
The type_info class. Used to hold the type information returned by thetypeid operator. 
 class type_info { 
 public:
 virtual ~type_info(); private:
 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;
 
 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 thetype-id or the type of theexpression, depending on which form oftypeid is used. 
 
 C++ Code1
 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 的条件
 //1、开启运行时类型信息;2、应用在具有多态关系的继承体系上;
 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); 
 二、类与类之间的关系 Unified Modeling Language (UML)又称统一建模语言或标准建模语言,是始于1997年一个OMG标准,它是一个支持模型化和软件系统开发的图形化语言。 
 1、继承(泛化)Generalization 
 Manager 继承自Employee. 
 2、关联 Association,单向关联 DirectedAssociation 
 
 Order 作为Customer 的成员,如vector<Order> orders ; 
 3、聚合 Aggregation class B class A { public: B* b_; }; 当A释放时,不负责B的释放,也许B是被共享的。 
 4、组合 Composition 
 当Company 释放时要负责Department 的释放,Department 不是共享的。 
 5、依赖 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++编程规范
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号