什么是dynamic_cast?
它可以用于向上转型(子类向基类)以及向下转型(基类向子类)
- 向上转型只需要将子类的指针或者引用赋给基类的指针或者引用。
- 向下转型是将基类的指针或者引用安全的赋给子类的指针过引用。但是需要父类有虚函数,因为dynamic_cast运行时需要检查RTTI信息,只有存在虚函数的类才会检查。
当某类继承AB两类,那么AB直接可以横向转型!
如下:
image.png
什么是RTTI(Run Time Type identification)机制?
通过运行时的类型识别,程序能够使用基类指针或引用来检查这些指针所指向的对象的实际派生类类型。简要来说,就是可以让你知道某一指针指向的类型。
最简单的RTTI包括以下两点
- 类识别
- 继承关系,即支持动态转换类型
RTTI机制可能会带来的副作用是什么?
破坏类的封装性
//假设Cricle与Rectangle是由Figure派生出来的子类,它们都有各自的draw函数
//当c++提供了RTTI机制后,就可以写出下面这个函数
void drawing( Figure *p )
{
if( typeid(*p).name() == "Circle" )
((Circle*)p) -> draw();
if( typeid(*p).name() == "Rectangle" )
((Rectangle*)p) -> draw();
}
如果Figure再派生出子类,那么又需要再改变drawing函数,这就破坏了类的封装性。
当我们不使用RTTI机制,我们必须使用虚函数来保持多态性,所以我们将drawing函数声明为虚函数
RTTI机制解决实际问题
假设现在有一个基类A,它有多个派生类BCD,每个派生类在判断对象相等时都有自己特定的判断方式,如何实现?
我们很容易就可以想到使用虚函数,但思考一下,虚函数的形参在基类和派生类中必须相同,那么equal函数只能比较基类成员而不能比较派生类成员。所以我们可以使用RTTI机制来实现,dynamic_cast可以转型为需要比较的派生类,typeid可以判断当前比较的对象是否为相同类型
Class Base{
friend bool operator ==(const Base&,const Base&);
public:
protected:
virtual bool equal(const Base&) const;
};
Class Derived:public Base{
protected:
bool operator ==(const Base&lhs,const Base&rhs)
{
return typeid(lhs)==typeid(rhs)&&lhs.equal(rhs);
}
bool equal(const Base &rhs) const
{
auto r=dynamic_cast<const Derived&>(rhs);
}
}
RTTI机制提供了两个操作符:typied、dynamic_cast
什么是typeid?
它可以返回当前变量的指向的对象
Figure *f = new Square();
cout<<typeid(*f).name()<<endl; //输出Square
网友评论