Effective C++读书笔记(16)(二)

2014-11-24 12:20:06 · 作者: · 浏览: 1




3)const_cast < type_id > ( expression )

  该运算符用来修改类型的const或volatile属性。除了const或volatile修饰之外,type_id和expression的类型是一样的。

  ①常量指针被转化成非常量指针,并且仍然指向原来的对象;

  ②常量引用被转换成非常量引用,并且仍然指向原来的对象;

  ③常量对象被转换成非常量对象。

Volatile和const类似。

Volatile:同const、static一样,这是一个类型修饰符。一个使用volatile修饰的变量,比如volatileint i; 每次对该变量的直接引用,都会访问内存,而不是从寄存器中读取(如果其已经在寄存器中)。这样一来,volatile似乎没什么用处,反倒会使数据的读取相对变慢很多,如果没有volatile,编译器可能会优化你的程序,使得数据从寄存器中读取,从而加快程序的运行。但如果这个变量是同其它进程/线程共享的,就可能造成数据的不一致。多线程情况下,你可以使用互斥机制来保证对共享数据访问的原子性。但是,在单片机等嵌入式环境中,硬件经常不会有这种互斥机制的支持,这时某些共享的数据(比如端口)就可能会产生不一致的情况。而使用volatile就会使编译器不对代码进行优化,每次对该变量的访问都会从内存中读取。

4)reinterpret_cast < type_id > ( expression )

该操作符修改了操作数类型,但仅仅是重新解释了给出的对象的比特模型而没有进行二进制转换。例如:

int *n= new int;

  double*d=reinterpret_cast (n);

  在进行计算以后, d 包含无用值. 这是因为reinterpret_cast仅仅是复制n比特位到d, 没有进行必要的分析。

这个关键词在我们需要把类型映射回原有类型时用到它。我们映射到的类型仅仅是为了故弄玄虚和其他目的,这是所有映射中最危险的。因此,需要谨慎使用reinterpret_cast.



旧风格的强制转型依然合法,但是新的形式更可取。首先,在代码中它们更容易识别,简化了在代码中寻找类型 系统被破坏的地方的过程。第二,更精确地指定每一个强制转型的目的,使得编译器诊断使用错误成为可能。例如,如果你试图将常量性去掉,除非使用新式转换的const_cast,否则无法通过编译。

唯一使用旧式转换的时机是当我要调用一个explicit构造函数传递一个对象给一个函数的时候,例如:

class Widget {
public:
explicit Widget(int size);
...
};

void doSomeWork(const Widget& w);

doSomeWork(Widget(15)); // 以int加上函数风格的转型动作创建Widget

doSomeWork(static_cast(15)); //以int加上C++风格的转型动作创建Widget


摘自 pandawuwyj的专栏