upcasting and downcasting

新学到的,针对类的转换符:

dynamic_cast, static_cast, reinterpret_cast, const_cast

这些转换符的使用,是当函数不是类的成员函数时,但需要调用之,并且传入的参数是对象时。

 

dynamic_cast: 使用内部的运行时类型信息数据结构,完成类型检查和转换操作。它可以完成upcasting,和downcasting,

如果转换失败,它会返回一个0,或者抛出一个std::bad_cast错误。

注意:当基类存在虚函数时,才能使用dynamci_cast。而且必须包含《typeinfo》头文件。而且类型的转换必须在同一个层次结构中。

 

static_cast:不进行运行时检查,而且做转换的基类和派生类不必非要在同一个多态的类层次结构中。它在对不在同一个类层次结构中的

类型进行静态的类型检查。

注意:如果要从基类向下强制转换到派生类,这种转换并非总是安全的。强制转换可能产生一个不同的,可能无效的地址。

例子:

class C : public A, public B{}

B *pb;

// pb is somehow initialized

..........

C *pc = static_castpb;

如果pb指向一个C类型对象,强制转换可以正常工作。如果它指向一个B类型的对象,可以强制转换,但地址不对。类似的,如果指针指向

一个基类对象,而我们用派生类指针访问不存在的派生类对象的成员,就可能造成不可预知的后果。《如果不能确定强制转换是否安全,

可以使用dynamic_cast对指针或引用进行向下的强制转换,然后检查结果是否正确》

 

reinterpret_cast:主要是为了取代C风格的强制类型转换用法,没有太大的使用。

 

const_cast: 主要是为了去掉对象的const属性,或者说是在const成员函数中,将this指针转换成对象本身的指针)。

为什么要这么做呢?   我们常看到: 一个对象被定义成const属性,那么它就只能去调用const成员函数,而对于一些类的成员变量是

用来管理对象的,并不是给用户使用的。它们处理用户不关心的隐藏数据,而且它们必须这样做,而不考虑对象是不是const。

例如:

class AnObject

{

int value;

int repetition;

public:

AnObject(int v) : value(v), repetition(0) {}

void report()   const;

}

 

void AnObject::report() const

{

const_castthis->repetition++;

std::cout<< repetition << std::endl;

}

 

int main()

{

const AnObject a(123);

a.report();

a.report();

return 0;

}

如果report成员函数不是const的,程序就不能为const类对象使用该成员函数。A::report数据本身需要递增repetition数据成员,

这种操作在const成员函数中不允许,因为const函数不能修改数据值。为了强制去掉对象的const属性,以便完成递增操作,函数

使用了const_cast运算符把this指针强制转换成非const类对象的指针。

 

一个另外的解决办法就是将成员变量声明为mutable,mutable表示数据绝不具有const属性,但是这个类可以被实例化成一个

const对象。如果变量被声明为mutable那么const成员函数才可以修改数据成员,一个强大的功能!!

 

 

你可能感兴趣的:(upcasting and downcasting)