1. 类型识别

(1)在面向对象中可能出现下面的情况

  ①基类指针指向子类对象

  ②基类引用成为子类对象的别名

静态类型——变量(对象)自身的类型(定义变量类型时类型或参数类型

动态类型——指针(引用)所指向的对象的实际类型

(2)基类指针转子类指针:

  ①示例:Derived* d = static_cast<Derived*>(pBase); //危险的转换方式

  ②问题:不安全,是否能强制类型转换取决动态类型

2. 利用多态获取动态类型

(1)解决方案

  ①在基类中定义虚函数,并返回具体的类型信息

  ②所有的派生类都必须实现类型相关的虚函数

  ③每个类中的类型虚函数都需要不同的实现

【编程实验】动态类型识别

#include <iostream>
#include <string>

using namespace std;

class Base
{
public:
    //在基类中提供个用来判断类型的虚函数
    //并且所有的派生类中都必须实现这个函数
    virtual string type()
    {
        return "Base";  //手动返回一个用于识别的标识符
    }
};

class Derived : public Base
{
public:
    string type()
    {
        return "Derived";
    } 

    void print()
    {
        cout << "I'm a Derived." << endl;
    }
};

class Child : public Base
{
public:
    string type()
    {
        return "Child";
    }
};

void test(Base* b)
{
    //危险的转换方式。因为b可能实际类型可能不是Derived的类型
    //Derived* d = static_cast<Derived*>(b);

    if(b->type() == "Derived")
    {
        Derived* d = static_cast<Derived*>(b);
        d->print();
    }
    //如果类中没有虚函数表,则调用dynamic_cast会直接报错,编译不过。
    //当父、子类没有继承关系时,dynamic_cast返回false,否则会转换后
    //实际对象的地址
    cout <<  dynamic_cast<Derived*>(b) << endl;
}

int main()
{
    Base b;
    Derived d;
    Child c;

    test(&b); //Base与Base没有继承关系,dynamic_cast返回false
    test(&d);  //Derived与Base有继承关系,dynamic_cast转换后对象的地址
    test(&c);  //Child与Derived没有继承关系,返回false

    ;
}
/*输出结果:
0
I'm a Derived.
0x23feb8
0
*/

(2)多态解决方案的缺陷

  ①必须从基类开始提供类型虚函数

  ②所有的派生类都必须重写类型虚函数

  ③每个派生类的类型名必须唯一

3. 类型识别关键字:typeid(须#include<typeinfo>)

(1)typeid关键字

  ①typeid关键字返回对应参数的类型信息

  ②typeid返回一个type_info类的对象

  ③当typeid的参数为NULL时抛出异常

(2)typeid关键字的使用

;

const type_info& tiv = typeid(i);   //得到变量i的类型信息

const type_info& tii = typeid(int); //得到int类型信息

(3)typeid的注意事项

  ①当参数为类型时:返回静态类型信息

  ②当参数为变量时:

    A.不存在虚函数表时:返回静态类型信息

    B.存在虚函数表时:返回动态类型信息

【编程实验】typeid类型识别

#include <iostream>
#include <string>
#include <typeinfo> //for typeid

using namespace std;

class Base
{
public:
    virtual ~Base(){}
};

class Derived : public Base
{
public:
    void print()
    {
        cout << "I'm a Derived." << endl;
    }
};

void test(Base* b)
{
    //const type_info& tb = typeid(b); //判断b的类型,Base*或Derived*
    const type_info& tb = typeid(*b);  //判断对象的类型

    cout << tb.name() << endl;
}

int main()
{
    ;

    const type_info& tiv = typeid(i);    //判断变量的类型
    const type_info& tii = typeid(int);  //判断类的类型

    cout << (tiv == tii) << endl;  //相等

    Base b;
    Derived d;

    test(&b);
    test(&d);

    ;
}
/*输出结果:
1
4Base       //g++下类名前面的数字表示类名的长度
7Derived
*/

4. 小结

(1)C++中有静态类型和动态类型的概念

(2)利用多态能够实现对象的动态类型识别

(3)typeid是专用于类型识别的关键字

(4)typeid能够返回对象的动态类型信息

第66课 C++中的类型识别的更多相关文章

  1. JS中的类型识别

    JS为弱类型语言,所以类型识别对JS而言尤为重要,JS中常用的类型识别方法有4种:typeof.Object.prototype.toString.constructor和instanceof. (1 ...

  2. C++中的类型识别

    1,为什么会提出类型识别概念呢? 1,为什么在 C 语言中没有提出这个概念呢,就是因为在 C++ 中引入了面向对象的特性,面向对象里面有一个非常重要的原则就是赋值兼容性原则: 2,在面向对象中可能出现 ...

  3. 框架原理第二讲,RTTI,运行时类型识别.(以MFC框架讲解)

    框架原理第二讲,RTTI,运行时类型识别.(以MFC框架讲解) 一丶什么是RTTI,以及RTTI怎么设计 通过第一讲,我们知道了怎么样升成一个窗口了,以及简单的消息循环. 第二讲则是主要讲解RTTI ...

  4. 关于js中的类型内容总结(类型识别)

    JS 有7种数据类型: 6种原始类型:Boollean    String   Number    Null    Underfined   Symbol 引用类型:Object 类型识别主要有以下四 ...

  5. C++之运行时类型识别RTTI

     C++ Code  12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 ...

  6. RTTI 运行时类型识别 及异常处理

    RTTI   运行时类型识别 typeid  ------  dynamic_cast dynamic_cast 注意事项: 1.只能应用于指针和引用之间的转化 2.要转换的类型中必须包含虚函数 3. ...

  7. RTTI (Run-Time Type Identification,通过运行时类型识别) 转

    参考一: RTTI(Run-Time Type Identification,通过运行时类型识别)程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型.   RTTI提供了以下两个 ...

  8. Scala 深入浅出实战经典 第49课 Scala中Variance代码实战(协变)

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  9. 数据库中字段类型对应的C#中的数据类型

    数据库中字段类型对应C#中的数据类型: 数据库                 C#程序 int int32 text string bigint int64 binary System.Byte[] ...

随机推荐

  1. html5标签的改变

    1.新的文档类型声明 浏览器解析html模式是有两种模式,按照各自浏览器的定义渲染的页面叫“怪异模式”,而按照w3c组织统一的标准渲染叫“标准模式”.一般都是使用标准模式来保持网页兼容性,区分这两种模 ...

  2. 使用 jQuery Mockjax 插件模拟 Ajax 请求

    在实际的开发过程中,前端后台协商好了统一的接口,就各自开始自己的任务了.这时候我有这么一个 Ajax 请求需要从后台获取数据: $.ajax({ url: '/products/' }).done(f ...

  3. 8月7号晚7点Autodesk北京办公室,我们来聊聊HTML5/ WebGL 3D 模型浏览技术

    Autodesk 发布了一款完全无需插件的三维模型浏览器 Autodesk 360 Viewer,大家有没有兴趣,下班后过来聊聊吧!   8月7号 周四, 19:00~21:00 Autodesk北京 ...

  4. 为ListView组件加上快速滑块以及修改快速滑块图像

    本文转载自:http://blog.csdn.net/ouyang_peng/article/details/46919723 作者:欧阳鹏  欢迎转载,与人分享是进步的源泉! 转载请保留原文地址:h ...

  5. iOS UIProgressView控件用法

    IOS中进度条控件的用法总结. 进度条控件是IOS开发中一个简单的系统控件,使用总结如下: 初始化一个进度条: - (instancetype)initWithProgressViewStyle:(U ...

  6. App Transport Security has blocked a cleartext

    错误描述: App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecu ...

  7. windows svn 上传后 自动部署 到web目录下

    第一步 把web目录设置为工作目录 "D:\Program Files (x86)\VisualSVN Server\bin\svn.exe" upgrade "D:\y ...

  8. mac 终端 常用指令

    开始正式研究ios 应用开发,由于是从C开始学起,所以学习下常用的mac终端指令,方便后续常用操作. mac 终端 常用指令: 1.ls指令 用途:列出文件 常用参数 -w 以简洁的形式列出所有文件和 ...

  9. C#问题

    1.结构体里面是否可以有属性? 可以有属性.实测代码以及截图. In C#, we can use the following statement to convert a string s to a ...

  10. 用CSS3实现背景的固定

    今天放假了,正好最近养成了没事泡泡博客园的习惯,自己也有了博客..不得不吐槽一下博客园为什么页面这么古朴,,带的几个模版也没啥意思,反正不符合我口味,幸亏后台提供了编辑CSS的功能,于是我就搬来现有的 ...