int ival = 3;
double dval = 3.14159;
// ival 被提升为double 类型: 3.0 (是一种保值转换)
ival + dval;
2、用一种类型的表达式赋值给另一种类型的对象。在这种情况下,目标转换类型是被赋值对象的类型。例如,在下面第一个赋值中文字常量0 的类型是int 它被转换成int*型的指针表示空地址在第二个赋值中double 型的值被截取成int 型的值。
int *pi = 0;
// dval 被截取为int值3 (这不是保值转换),一般情况下编译器会给出warning.
ival = dval;
extern double sqrt( double );
// 2 被提升为double 类型: 2.0
cout << "The square root of 2 is "<< sqrt( 2 ) << endl;
4、从一个函数返回一个表达式,表达式的类型与返回类型不相同。在这种情况下,目标转换类型是函数的返回类型。例如:
double difference( int ival1, int ival2 ){
// 返回值被提升为double 类型
return ival1 - ival2;
}
// C++强制转换符号
type(expr);
// C 语言强制转换符号
(type)expr;
旧式强制转换可以用来代替标准C++中的static_cast,cons_cast 或reinterpret_cast。在标准C++之前,我们只能使用旧式强制转换。如果我们希望自己的代码在C++和C 语言中都能够编译的话,那么只能使用C 语言的强制转换符号。
const char *pc = (const char*) pcom;
int ival = (int) 3.14159;
extern char *rewrite_str( char* );
char *pc2 = rewrite_str( (char*) pc );
int addr_value = int( &ival );
对旧式强制转换符号的支持是为了对在标准C++之前写的程序保持向后兼容性以及提供与C 语言兼容的符号。
该运算符把exdivssion转换为type-id类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:
①用于类层次结构中基类和子类之间指针或引用的转换。
进行上行转换(把子类的指针或引用转换成基类表示)是安全的;
进行下行转换(把基类指针或引用转换成子类表示)时,由于没有动态类型检查,所以是不安全的。
②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开
③把空指针转换成目标类型的空指针。
④把任何类型的表达式转换成void类型。
用法:dynamic_cast < type-id > ( exdivssion )
该运算符把exdivssion转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void *;
如果type-id是类指针类型,那么exdivssion也必须是一个指针,如果type-id是一个引用,那么exdivssion也必须是一个引用。
在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
class B{
public:
int m_iNum;
virtual void foo();
};
public:
char *m_szName[100];
};
D *pd1 = static_cast(pb);
D *pd2 = dynamic_cast(pb);
}
但是,如果pb指向的是一个B类型的对象,那么pd1将是一个指向该对象的指针,对它进行D类型的操作将是不安全的(如访问m_szName),
而pd2将是一个空指针。
class A{
public:
int m_iNum;
virtual void f(){}
};
};
};
B *pb = new B;
pb->m_iNum = 100;
D *pd2 = dynamic_cast(pb); //pd2 is NULL
delete pb;
}
3、reinterpret_cast
type-id必须是一个指针、引用、算术类型、函数指针或者成员指针。
它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还可以得到原先的指针值)。该运算符的用法比较多。
4、const_cast
用法:const_cast<type-id> (exdivssion)
该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外, type_id和exdivssion的类型是一样的。
常量指针被转化成非常量指针,并且仍然指向原来的对象;
常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。Voiatile和const类试。举如下一例:
class B{
public:
int m_iNum;
}
void foo(){
const B b1;
b1.m_iNum = 100; //comile error
B b2 = const_cast(b1);
b2. m_iNum = 200; //fine
}
上面的代码编译时会报错,因为b1是一个常量对象,不能对它进行改变;
使用const_cast把它转换成一个常量对象,就可以对它的数据成员任意改变。注意:b1和b2是两个不同的对象。
== ===========================================
== dynamic_cast .vs. static_cast
== ===========================================class B { ... };
class D : public B { ... };void f(B* pb)
{D* pd1 = dynamic_cast(pb);D* pd2 = static_cast(pb);
}
== ===========================================
== static_cast .vs. reinterpret_cast
== ===========================================
int n=9; double d=static_cast < double > (n);
int n=9;double d=reinterpret_cast (n);
这次, 结果有所不同. 在进行计算以后, d 包含无用值. 这是因为 reinterpret_cast 仅仅是复制 n 的比特位到 d, 没有进行必要的分析.
这篇文章其实并不是不才的原创,本来打算自己写的,但是通过baidu一下,发现有兄弟写出来了,就干脆摘录下来,供大家参考使用了!
详情请看:
- 标准c++中主要有四种强制转换类型运算符:
- const_cast,reinterpret_cast,static_cast,dynamic_cast等等。
- 1)static_cast<T*>(a)
- 将地址a转换成类型T,T和a必须是指针、引用、算术类型或枚举类型。
- 表达式static_cast<T*>(a), a的值转换为模板中指定的类型T。在运行时转换过程中,不进行类型检查来确保转换的安全性。
- 例子:
- class B { ... };
- class D : public B { ... };
- void f(B* pb, D* pd)
- {
- D* pd2 = static_cast<D*>(pb); // 不安全, pb可能只是B的指针
- B* pb2 = static_cast<B*>(pd); // 安全的
- ...
- }
- class B { ... };
- class D : public B { ... };
- void f(B* pb, D* pd)
- {
- D* pd2 = static_cast<D*>(pb); // 不安全, pb可能只是B的指针
- B* pb2 = static_cast<B*>(pd); // 安全的
- ...
- }
- class B { ... };
- class D : public B { ... };
- void f(B* pb, D* pd)
- {
- D* pd2 = static_cast<D*>(pb); // 不安全, pb可能只是B的指针
- B* pb2 = static_cast<B*>(pd); // 安全的
- ...
- }
- 2)dynamic_cast<T*>(a)
- 完成类层次结构中的提升。T必须是一个指针、引用或无类型的指针。a必须是决定一个指针或引用的表达式。
- 表达式dynamic_cast<T*>(a) 将a值转换为类型为T的对象指针。如果类型T不是a的某个基类型,该操作将返回一个空指针。
- 例子:
- class A { ... };
- class B { ... };
- void f()
- {
- A* pa = new A;
- B* pb = new B;
- void* pv = dynamic_cast<A*>(pa);
- // pv 现在指向了一个类型为A的对象
- ...
- pv = dynamic_cast<B*>(pb);
- // pv 现在指向了一个类型为B的对象
- }
- 3)const_cast<T*>(a)
- 去掉类型中的常量,除了const或不稳定的变址数,T和a必须是相同的类型。
- 表达式const_cast<T*>(a)被用于从一个类中去除以下这些属性:const, volatile, 和 __unaligned。
- 例子:
- class A { ... };
- void f()
- {
- const A *pa = new A;//const对象
- A *pb;//非const对象
- //pb = pa; // 这里将出错,不能将const对象指针赋值给非const对象
- pb = const_cast<A*>(pa); // 现在OK了
- ...
- }
- class A { ... };
- void f()
- {
- const A *pa = new A;//const对象
- A *pb;//非const对象
- //pb = pa; // 这里将出错,不能将const对象指针赋值给非const对象
- pb = const_cast<A*>(pa); // 现在OK了
- ...
- }
- class A { ... };
- void f()
- {
- const A *pa = new A;//const对象
- A *pb;//非const对象
- //pb = pa; // 这里将出错,不能将const对象指针赋值给非const对象
- pb = const_cast<A*>(pa); // 现在OK了
- ...
- }
- 4)reinterpret_cast<T*>(a)
- 任何指针都可以转换成其它类型的指针,T必须是一个指针、引用、算术类型、指向函数的指针或指向一个类成员的指针。
- 表达式reinterpret_cast<T*>(a)能够用于诸如char* 到 int*,或者One_class* 到 Unrelated_class*等类似这样的转换,因此可能是不安全的。
- 例子:
- class A { ... };
- class B { ... };
- void f()
- {
- A* pa = new A;
- void* pv = reinterpret_cast<A*>(pa);
- // pv 现在指向了一个类型为B的对象,这可能是不安全的
- ...
- }
大 |
中 |
小


2006/07/15
06:19
29436

500

被折叠的 条评论
为什么被折叠?



