1 静态类型与动态类型
面向对象中可能有基类指针指向子类对象,基类引用成为子类对象的别名。如图所示,父类指针指向子类的对象,我们可以分为静态类型和动态类型。
静态类型:变量(对象)自身的类型
动态类型:指针(引用)所指向对象的实际类型
看如下代码,进行类型转换,这样的转换安全吗?Base 是基类,Derived 是派生类,将父类指针强制转换为子类指针,这样安全吗,如果调用 test 函数时,传入的是 Base 类型的指针,转换是危险的,如果传入的是 Derived 类型的指针,转换过程是危险的。
所以基类指针是否可以强制类型转换为子类指针取决于动态类型。
C++ 中如何得到动态类型呢?接着向下看
2 typeid 获取类型信息
C++ 提供了 typeid 关键字用于获取类型信息
- typeid 关键字返回对应参数的类型信息
- typeid 返回一个 type_info 类对象
- 当 typeid 的参数围殴 NULL 时将抛出异常
通过一个例子看下 typeid 关键字的使用
#include<iostream>
using namespace std;
#include<typeinfo>
int main()
{
int i = 0;
const type_info& tiv = typeid(i);
const type_info& tii = typeid(int);
cout << (tiv == tii) << endl;
return 0;
}
typeid 的使用
- 当参数为类型时:返回静态类型信息
- 当参数为变量时:
- 不存在虚函数表:返回静态类型信息
- 存在虚函数表:返回动态类型信息
// 48-1.cpp
#include<iostream>
#include<typeinfo>
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);
cout << tb.name() << endl;
}
int main()
{
Base b;
Derived d;
test(&b);
test(&d);
return 0;
}
使用 typeid 可以获取类型信息,Base 的析构函数为虚函数,所以两个类中都有虚函数表,传入变量时,返回动态类型信息,可以判断传入的父类指针还是子类指针。
$ g++ 48-1.cpp -o 48-1
$ ./48-1
4Base
7Derived
3 小结
1、C++ 中有静态类型和动态类型的概念
2、typeid 关键字专门用于类型识别