C++:关于C++的四个类型转换运算符
2015-04-10 11:03
253 查看
C++严格地限制允许的类型转换,并添加了4个类型转换运算符:
1)dynamic_cast
2)const_cast
3)static_cast
4)reinterpret_cast
一,dynamic_cast运算符
假设:
class High{};
class Low{};
Hign * ph;
Low * pl;
当且仅当 Low 是High的可访问基类(直接或间接)时,下面的语句才将一个Low*指针赋给pl
否则上句将空指针赋给pl.
综述:dynamic_cast运算符用途是,使得能够在类层次结构中进行向上转换(由于是is-a关系,这样的转换是安全的),不允许其它转换。
二,const_cast 运算符
这里解释下volatile:
一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。
精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。
关于volatile的思考:
1)一个参数既可以是const还可以是volatile吗?解释为什么。
2)一个指针可以是volatile 吗?解释为什么。
3)下面的函数有什么错误:
1)是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。
2)是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。
3)这段代码有点变态。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:
表达式:const_cast<type_name>(experssion)
如果类型的其它方面也被修改,则上述类型的转换将出错,也就是说:
除了const 与volatile特征(有或无)可以不同外,type_name与expression的类型必须相同。
还是假设:High 与 Low 是两个类
有时候可能需要这样一个值,它在大多数时是常量,但有时又要是可以修改的。
在这种情况下,可将这个值申明为const,并在修改它的时候,使用cosnt_cast。
当然也可以用通用的类型转换,但通用类型转换可以同时改变类型。
const_cast 不是万能的,它可以修改指向一个值的指针,但可能无法修改const的值。
例:
const_cast 可以删除 const int * pt 中的const,
但如果pt指向的值也是const,则编译器可能禁止修改它。
三,static_cast 运算符
表达式: static_cast<type_name>(expression)
仅当 type_name 可以被隐式转换为 expression 或 expression 可被隐式转换为 type_name所属的类型时,上述转换才合法,否则出错。
假设Hign是Low的基类,Pond是一个无关的类,则从High到Low的转换,从Low到High的转换都是合法的,但从Low到Pond的转换是不允许的。
四,reinterpret_cast 运算符
表达式:reinterpret_cast<type_name>(expression)
该运算符用于天生危险的类型转换,它不允许删除const,但会做其它操作。
示例:
struct dat
{
short a;
short b;
};
long value = 0xA224B118;
dat * pd = reinterpret_cast<dat *>(&value);
std::cout << hex << pd->a; //display first 2 bytes of value注:不同的操作系统在存储多字节整型时,可能以不同的顺序存储其中的字节。
reinterpret_cast 运算符并不支持所有的类型转换。
如:
1)可以将指针类型转换为足以存储指针表示的整型,但不能将指针转换为更小的整型或浮点型。
2)不能将函数指针转换为数据指针。
下面是对是错:
char ch = char(&d);
在C中是允许的,但在C++中通常不允许,因为char类型都太小,不能存储指针。
1)dynamic_cast
2)const_cast
3)static_cast
4)reinterpret_cast
一,dynamic_cast运算符
假设:
class High{};
class Low{};
Hign * ph;
Low * pl;
当且仅当 Low 是High的可访问基类(直接或间接)时,下面的语句才将一个Low*指针赋给pl
pl = dynamic_cast<Low*>(ph);
否则上句将空指针赋给pl.
综述:dynamic_cast运算符用途是,使得能够在类层次结构中进行向上转换(由于是is-a关系,这样的转换是安全的),不允许其它转换。
二,const_cast 运算符
这里解释下volatile:
一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。
精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。
关于volatile的思考:
1)一个参数既可以是const还可以是volatile吗?解释为什么。
2)一个指针可以是volatile 吗?解释为什么。
3)下面的函数有什么错误:
int square(volatile int *ptr) { return *ptr * *ptr; }答案:
1)是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。
2)是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。
3)这段代码有点变态。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:
int square(volatile int *ptr) { int a,b; a = *ptr; b = *ptr; return a * b; }由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:
long square(volatile int *ptr) { int a; a = *ptr; return a * a; }const_cast 运算符该运算符用于执行只有 一种用途的类型转换,即改变值为 const 或 volatile.
表达式:const_cast<type_name>(experssion)
如果类型的其它方面也被修改,则上述类型的转换将出错,也就是说:
除了const 与volatile特征(有或无)可以不同外,type_name与expression的类型必须相同。
还是假设:High 与 Low 是两个类
High high; const High * ph = &high; High * ph2 = const_cast<High *>(ph); // valid -- High * 与 const Hign *,忽略const,相同 const Low * pl = const_cast<const Low *>(ph); // invalid -- const Low * 与 const Hign *,忽略const,不同提供const_cast运算符的原因:
有时候可能需要这样一个值,它在大多数时是常量,但有时又要是可以修改的。
在这种情况下,可将这个值申明为const,并在修改它的时候,使用cosnt_cast。
当然也可以用通用的类型转换,但通用类型转换可以同时改变类型。
High high; const High * ph = &high; High * ph2 = (High *)ph; // valid Low * pl = (Low *)ph; // also valid由于编程时可能同时改变类型与常量特征,因此const_cast运算符更安全。
const_cast 不是万能的,它可以修改指向一个值的指针,但可能无法修改const的值。
例:
#include <iostream> using std::cout; using std::endl; void change(const int * pt, int n); int main() { int pop1 = 38383; //非const值 const int pop2 = 2000; //const值 cout << "pop1, pop2: " << pop1 << ", " << pop2 << endl; change(&pop1, -103); change(&pop2, -103); cout << "pop1, pop2: " << pop1 << ", " << pop2 << endl; return 0; } void change(const int * pt, int n) //都用一个const类型的指针指向pop1,pop2 { int * pc; pc = const_cast<int *>(pt); *pc += n; }结果:
pop1, pop2: 38383, 2000 pop1, pop2: 38280, 2000 请按任意键继续. . .上述结果说明了:
const_cast 可以删除 const int * pt 中的const,
但如果pt指向的值也是const,则编译器可能禁止修改它。
三,static_cast 运算符
表达式: static_cast<type_name>(expression)
仅当 type_name 可以被隐式转换为 expression 或 expression 可被隐式转换为 type_name所属的类型时,上述转换才合法,否则出错。
假设Hign是Low的基类,Pond是一个无关的类,则从High到Low的转换,从Low到High的转换都是合法的,但从Low到Pond的转换是不允许的。
High high; Low low; High * ph = static_cast<High *>(&low); // valid Low * pl = static_cast<Low *>(&high); // valid Pond * pp = static_cast<Pond *>(&low); // invalid
四,reinterpret_cast 运算符
表达式:reinterpret_cast<type_name>(expression)
该运算符用于天生危险的类型转换,它不允许删除const,但会做其它操作。
示例:
struct dat
{
short a;
short b;
};
long value = 0xA224B118;
dat * pd = reinterpret_cast<dat *>(&value);
std::cout << hex << pd->a; //display first 2 bytes of value注:不同的操作系统在存储多字节整型时,可能以不同的顺序存储其中的字节。
reinterpret_cast 运算符并不支持所有的类型转换。
如:
1)可以将指针类型转换为足以存储指针表示的整型,但不能将指针转换为更小的整型或浮点型。
2)不能将函数指针转换为数据指针。
下面是对是错:
char ch = char(&d);
在C中是允许的,但在C++中通常不允许,因为char类型都太小,不能存储指针。
相关文章推荐
- C++的四个类型转换运算符
- (转载)C++的四个类型转换运算符
- 关于c++ 强制转换类型运算符 static_cast、dynamic_cast、reinterpret_和const_cast
- 关于c++ 强制转换类型运算符 static_cast、dynamic_cast、reinterpret_和const_cast
- 转:关于C++中的类型转换
- 关于C++中的类型转换
- C++的四个类型转换
- C++中的四种类型转换运算符,摘自网络
- 关于C++中的类型转换
- c++ 强制转换类型运算符
- 分享:C++中四种类型转换运算符的使用方法
- c++中主要有四种强制转换类型运算符
- 关于linux下C++中利用socket时的数据类型转换错误
- 关于C++中的类型转换
- C++中四种类型转换运算符的使用方法
- C++类型转换运算符(Type Conversion Operators)
- C++类型转换运算符的使用方法
- 标准C++的四种强制转换类型运算符
- [转载] 标准C++的四种强制转换类型运算符
- C++中四种类型转换运算符的使用方法