c++ cast operator(类型转换操作符)

复制于:http://xiaochonganty.blog.163.com/blog/static/48527932008931104132748/

New Cast Operators

Originally, the C++ standardization committee wanted to deprecate C-style casting, thereby enforcing the use of the new cast operators exclusively. However, because C-style casts are widely used in legacy code and because many C++ compilers serve as C compilers, the committee decided against doing so. That said, C++ programmers are encouraged to use the new cast operators.

Before I present these operators, let‘s see why C-style cast has fallen out of favor. Consider the following code listing:

void *p=&x;int n=(int)p; //C-style cast

The C-style cast seems harmless at first sight. Yet, it has several potential dangers. First, it performs different operations in different contexts. For example, it may perform a safe int to doublepromotion, but it can also perform inherently dangerous operations such as casting void* to a numeric value (as in the example above). The programmer can‘t always tell from the source code if the cast is safe or inherently dangerous.

Worse, a C-style cast may perform multiple operations at once. In the following example, not only does it cast char * to unsigned char *, but it also removes the const qualifier at the same time:

const char *msg="don‘t touch!";unsigned char *p=(unsigned char*) msg; // intentional?

Again, you cannot tell whether this was the programmer‘s intention or an oversight.

The New Cast Operators

The ailments of C-style cast have been known for years. C++ offers a superior alternative in the form of new cast operators. They document the programmer‘s intent more clearly while preserving the compiler‘s ability to catch potential bugs like the ones shown above. C++ has four new cast operators:

static_cast const_cast reinterpret_cast dynamic_cast

The dynamic_cast operator is unique, as it introduces new functionality that C-style cast doesn‘t support. I‘ll get to that momentarily.

static_cast

static_cast performs safe and relatively portable casts. For example, you use static_cast to explicitly document a cast that would otherwise take place automatically. Consider the following example:

bool b=true;int n=static_cast<int> (b);

C++ automatically casts bool to int in this context so the use of static_cast in this case isn‘t necessary. However, by using it, programmers document their intention explicitly.

In other contexts, static_cast is mandatory. For example, when you cast void* to a different pointer type, as in the following example:

int n=4;void *pv=&n;int pi2 = static_cast<int *> (pv); //mandatory

static_cast uses the information available at compile time to perform the required type conversion. Therefore, the target and the source might not be identical in their binary representation. Consider a float to int conversion. The binary representation of the floating number 10.0 is quite different from the equivalent integer value of 10. static_cast performs the necessary adjustments when casting one to the other.

The use of static_cast enables the compiler to catch programmers‘ mistakes such as this:

const char *msg="don‘t touch!";unsigned char *p= static_cast<unsigned char*> (msg); //error

Here the compiler issues an error message indicating that the cast operation attempts to remove the const qualifier of msg -- something that the programmer probably didn‘t intend anyway.

const_cast

The removal of const requires a special cast operator called const_cast. This operator may perform only the following operations:

Remove the const and or volatile qualification;Add const and or volatile qualification

For example

struct A{ void func(){} // non-const member function};void f(const A& a) { a.func(); // error, calling a non-const function }

Clearly, this is a design mistake. The member function func() should have been declared constin the first place. However, such code does exist in third-party libraries; when innocent programmers try to use it, they have to resort to brute force casts. To overcome this problem, you may remove theconst qualifier of a and then call func() as follows:

A &ref = const_cast<A&> (a); // remove constref.func(); // now fine

Trying to perform any other conversion with const_cast will result a compilation error. Remember also that while const_cast may remove the const qualifier of an object, this doesn‘t mean that you‘re allowed to modify it. In fact, trying to modify a const object causes undefined behavior. Therefore, useconst_cast cautiously when it is used for the removal of const or volatile.

reinterpret_cast

As opposed to static_castreinterpret_cast performs relatively dangerous and nonportable casts. reinterpret_cast doesn‘t change the binary representation of the source object. Therefore, it is often used in low-level applications that convert objects and other data to a stream of bytes (and vice versa). In the following example, reinterpret_cast is used to "cheat" the compiler, enabling the programmer to examine the individual bytes of a float variable:

float f=10;unsigned char *p = reinterpret_cast <unsigned char*> (&f);for (int j=0; j<4; ++j) cout<<p[j]<<endl;

The use of reinterpret_cast explicitly warns the reader that an unsafe (and probably a nonportable) conversion is taking place. When using reinterpret_cast, the programmer -- rather than the compiler -- is responsible for the results.

dynamic_cast

As previously said, dynamic_cast differs from all other three cast operators. You use it when the conversion must access the runtime type information of an object rather than its static type (for more information on static vs. dynamic typing, please refer to the "Runtime Type Information (RTTI)" section). Two common scenarios that necessitate the use of dynamic_cast are a <I>downcast</i> i.e., casting a base class pointer or reference to a pointer or reference of a derived class and a crosscast in which the programmer converts a multiply-inherited object to one of its secondary base classes.

Summary

C-style cast is neither safe nor explicit enough, as I have shown. It disables the compiler‘s type-safety checks, its syntactic form doesn‘t express the intended conversion clearly, and it cannot perform a dynamic cast. For all these reasons, you should avoid using it in new code.

Instead, use static_cast for safe and rather portable casts, const_cast to remove or add only the const/volatile qualifiers of an object, and reinterpret_cast for low-level, unsafe and nonportable casts. Use dynamic_cast for conversions that must access the dynamic type of an object and RTTI capability-queries.

其他参考http://en.wikibooks.org/wiki/C%2B%2B_Programming/Type_Casting

http://welfare.cnblogs.com/articles/336091.html

http://www.acm.org/crossroads/xrds3-1/ovp3-1.html

c++ cast operator(类型转换操作符)

时间: 2024-10-17 08:31:48

c++ cast operator(类型转换操作符)的相关文章

C++强制类型转换操作符 const_cast

const_cast也是一个强制类型转换操作符.<C++ Primer>中是这样描述它的: 1.将转换掉表达式的const性质. 2.只有使用const_cast才能将const性质性质转化掉.试图使用其他三种形式的强制转换都会导致编译时的错误.(添加const还可以用其他转换符,如static_const) 3.除了添加const或删除const特性,使用const_cast符来执行其他任何类型的转换都会引起编译错误.(volatile限定符也包括,不过我不怎么了解,本文主要说const)

RTTI,C++类型转换操作符

body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;} th{border: 1px solid gray; padding: 4px; background-color: #DDD;} td{border: 1px solid gray; padding: 4px;} tr:nth-child(

C++ operator overload -- 操作符重载

C++ operator overload -- 操作符重载 2011-12-13 14:18:29 分类: C/C++ 操作符重载有两种方式,一是以成员函数方式重载,另一种是全局函数. 先看例子 #include <iostream> #include <string> using namespace std; /* defualt operator= differ from my own one. * assign 0 or 1 to TEST_EQ, look the dif

C++强制类型转换操作符 dynamic_cast

dynamic_cast是四个强制类型转换操作符中最特殊的一个,它支持运行时识别指针或引用. >>>>>>>>>>>编译器的RTTI设置>>>>>>>>>>> dynamic_cast提供RTTI(Run-Time Type Information),也就是运行时类型识别.它对编译器有要求,需要编译器启动“运行时类型信息”这一选项.当编译器不开启RTTI时,运行含有dynam

C++ 四种类型转换操作符

一.C风格类型转换操作符 (type) expression 例子: int firstNumber, secondNumber; double result = ((double)firstNumber)/secondNumber: 二.C++类型转换操作符 1.static_cast  在功能上基本上与 C 风格的类型转换一样强大,含义也一样. double result = static_cast<double>(firstNumber)/secondNumber; 它也有功能上限制.例

c++四种类型转换操作符简要总结

1.  static_cast<target>(expression) 可用于存在继承关系的类指针/引用之间的向上向下转换.执行向下转换时没有安全检查(区别于dynamic_cast),所以如果实际类型与目标类型不符合,编译虽然可以通过,但运行时的后果未定义. void*指针转换为实际的指针 其他基本类型的隐式转换以及反方向的转换,如:int <-> double 2.  dynamic_cast<target>(expression) 只能用于target为类指针或者

C# to IL 5 Operator Overloading(操作符重载)

Every operator overload that we use in C#, gets converted to a function call in IL. Theoverloaded > operator translates into the function op_GreaterThan and a + gets convertedto op_Addition etc. In the first program of this chapter, we have overloade

operator= 复制操作符的意外

首先,看以下的代码的输出时什么: 上述代码做了最理所当然的事.就是将Derived的两个对象进行了交换.可是通过指针进行的赋值输出却不是预期的: 居然调用的是Base的operator=,也就意味着我们把d2的Base部分赋值给了d1.而如今的d1就是"通常是自己的derived,一半是d2的Base"的怪物啦! !! 看来编译器没有理会我们的意图,对于这种指针赋值都不能如愿,于是,我们须要的是动态类型,那么,我们能够将 "operator=虚化". 可是通过指针复

tf.cast()数据类型转换

tf.cast()函数的作用是执行 tensorflow 中张量数据类型转换,比如读入的图片如果是int8类型的,一般在要在训练前把图像的数据格式转换为float32. cast定义: cast(x, dtype, name=None)第一个参数 x:   待转换的数据(张量)第二个参数 dtype: 目标数据类型第三个参数 name: 可选参数,定义操作的名称 int32转换为float32: import tensorflow as tf t1 = tf.Variable([1,2,3,4,