第66课 C++中的类型识别
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++中的类型识别的更多相关文章
- JS中的类型识别
JS为弱类型语言,所以类型识别对JS而言尤为重要,JS中常用的类型识别方法有4种:typeof.Object.prototype.toString.constructor和instanceof. (1 ...
- C++中的类型识别
1,为什么会提出类型识别概念呢? 1,为什么在 C 语言中没有提出这个概念呢,就是因为在 C++ 中引入了面向对象的特性,面向对象里面有一个非常重要的原则就是赋值兼容性原则: 2,在面向对象中可能出现 ...
- 框架原理第二讲,RTTI,运行时类型识别.(以MFC框架讲解)
框架原理第二讲,RTTI,运行时类型识别.(以MFC框架讲解) 一丶什么是RTTI,以及RTTI怎么设计 通过第一讲,我们知道了怎么样升成一个窗口了,以及简单的消息循环. 第二讲则是主要讲解RTTI ...
- 关于js中的类型内容总结(类型识别)
JS 有7种数据类型: 6种原始类型:Boollean String Number Null Underfined Symbol 引用类型:Object 类型识别主要有以下四 ...
- C++之运行时类型识别RTTI
C++ Code 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 ...
- RTTI 运行时类型识别 及异常处理
RTTI 运行时类型识别 typeid ------ dynamic_cast dynamic_cast 注意事项: 1.只能应用于指针和引用之间的转化 2.要转换的类型中必须包含虚函数 3. ...
- RTTI (Run-Time Type Identification,通过运行时类型识别) 转
参考一: RTTI(Run-Time Type Identification,通过运行时类型识别)程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型. RTTI提供了以下两个 ...
- Scala 深入浅出实战经典 第49课 Scala中Variance代码实战(协变)
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- 数据库中字段类型对应的C#中的数据类型
数据库中字段类型对应C#中的数据类型: 数据库 C#程序 int int32 text string bigint int64 binary System.Byte[] ...
随机推荐
- Error: Error setting TTL index on collection : sessions
Error: Error setting TTL index on collection : sessions 一.步骤一: 这个问题一般是直接升级 mongodb和connect-mongo的版本为 ...
- go语言 类型:数组切片
初看起来,数组切片就像一个指向数组的指针,实际上它拥有自己的数据结构,而不仅仅是个指针.数组切片的数据结构可以抽象为以下3个变量: 1.一个指向原生数组的指针: 2.数组切片中的元素个数: 3.数组切 ...
- 数据连接到 Web 服务 InfoPath 2010 窗体中的 SharePoint 服务器上运行时的错误消息:"401-未经授权"解决方案
症状: 请考虑以下情形: Web 窗体发布到 SharePoint 服务器. 您创建 Microsoft InfoPath 2010 表单所在的 SharePoint 服务器上使用到位于数据的数据连接 ...
- Android Activity生命周期详讲
管理 Activity 生命周期 通过实现回调方法管理 Activity 的生命周期对开发强大而又灵活的应用至关重要. Activity 的生命周期会直接受到 Activity 与其他 Activit ...
- oc程序编译【-framework Foundation 编译】
第一种编译 第二种编译 -framework Foundation 编译
- 【代码笔记】iOS-侧滑效果
一,效果图. 二,工程图. 三,代码. AppDelegate.h #import <UIKit/UIKit.h> //加入头文件 #import "PPRevealSideVi ...
- 从零开始一个iOS项目(一)——基本准备以及cocopods的安装
项目开发分为:独立开发和迭代开发,我主要讲独立开发,若读者是迭代开发,希望公司的代码一定要规范,便能省去许多麻烦,也能从中获益,闲时也可接些外包,赚一些外快,也是美差,然而独立开发最能锻炼人的能力. ...
- 小试ildasm,ilasm,ilspy
选择了微耕的软件(为什么选择它,因为微耕的二次开发实在太牛了,只给文档,一切技术问题都不回答.文档也是只公开基本的东西) 第一个功能:换文字 第二个功能:插入一个新的程序集,在做某些事情前先做我想做的 ...
- DOS 下 mysql 导入.SQL
- CocoaPods安装以及相关问题解决
Mac OS X上安装 Ruby环境 安装RVM $ curl -L https://get.rvm.io | bash -s stable 关闭终端,新开另外一个终端(新打开的终端会自动载入RVM环 ...