1.在面向对象中可能出现下面的情况
(1)基类指针指向子类对象
(2)基类引用成为子类对象的别名
静态类型------变量(对象)自身的类型
动态类型------指针(引用)所指向对象的实际类型
基类指针是否可以强制类型转换为子类指针取决于动态类型,若指针指向子类就可以转换,指向父类就无法转换,所以C++中如何得到动态类型
解决方案:利用多态
-
在基类中定义虚函数返回具体的类型信息
-
所有的派生类都必须实现类型相关的虚函数
-
每个类中的类型虚函数都需要不同的实现
#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 << "Derived" << endl;
}
};
class Child :public Base {
public:
string type() {
return "Child";
}
};
void test(Base* b) {
// Derived* d = static_cast<Derived*>(b); 危险的转换方式
cout << b->type() << endl;
if (b->type() == "Derived") {
Derived* d = static_cast<Derived*>(b);
d->print();
}
cout << dynamic_cast<Derived*>(b) << endl; //dynamic_cast只能显示转换是否成功,但是无法知道转换后的结果
}
int main() {
Base b;
Derived d;
Child c;
test(&b);
test(&d);
test(&c);
}
运行结果:
Base
0000000000000000
Derived
Derived
00000014E231F698
Child
0000000000000000
但是上述方式的缺陷
- 必须从基类开始提供类型虚函数
- 所有的派生类都必须重写类型虚函数
- 每个派生类的类型名必须唯一
C++提供了typeid关键字用于获取类型信息
- typeid关键字返回对应参数的类型信息
- typeid返回一个type_info类对象
- 当typeid的参数为NULL时将抛出异常
注意事项
-
当参数为类型时:返回静态类型信息
-
当参数为变量时:不存在虚函数表------返回静态类型信息;存在虚函数表------返回动态类型信息
#include<iostream>
#include<string>
#include<typeinfo>
using namespace std;
class Base {
public:};
class Derived :public Base {
public:
void printf() {
cout << "Derived" << endl;
}
};void test(Base* b) {
const type_info& tb = typeid(*b);
cout << tb.name() << endl;
}
int main() {
int i = 0;
const type_info& tiv = typeid(i);
const type_info& tii = typeid(int);
cout << (tiv == tii) << endl; //1
Base b;
Derived d;
test(&b); //class Base
test(&d); //class Base
return 0;
}
由于b指针所指向的对象没有虚函数表,所有返回静态类型信息
#include<iostream>
#include<string>
#include<typeinfo>
using namespace std;
class Base {
public:
virtual ~Base() {
}
};
class Derived :public Base {
public:
void printf() {
cout << "Derived" << endl;
}
};
void test(Base* b) {
const type_info& tb = typeid(*b);
cout << tb.name() << endl;
}
int main() {
int i = 0;
const type_info& tiv = typeid(i);
const type_info& tii = typeid(int);
cout << (tiv == tii) << endl; //1
Base b;
Derived d;
test(&b); //class Base
test(&d); //class Derived
return 0;
}
存在虚函数表------返回动态类型信息