当一个是无符号类型,另一个是带符号类型:
若是无符号不小于带符号,那么带符号转换成无符号。
若是无符号小于带符号,当无符号类型的全部值都能存到带符号中时,则无符号转换成带符号,不然,
带符号类型转换成无符号类型。
好比:
有两个类型分别是 long 和 unsigned int,若是大小相同,long类型转换成unsigned int,不然unsigned转换成long类型ios
数组转换成指针:
decltype,取地址&,sizeof以及typeid(未知)不会转换
若是用一个引用初始化数组也不会发生转换。(引用初始化数组?)c++
类类型定义的转换:程序员
string s; while(cin >> s) //IO库定义了从istream向bool的转换规则,取决因而否读入成功 { }
cast-name
主要在如下几种场合中使用:
1.用于类层次结构中,基类和子类之间指针和引用的转换;
当进行上行转换,也就是把子类的指针或引用转换成父类表示,这种转换是安全的;
当进行下行转换,也就是把父类的指针或引用转换成子类表示,这种转换是不安全的,也须要程序员来保证;
2.用于基本数据类型之间的转换,如把int转换成char,把int转换成enum等等,这种转换的安全性须要程序员来保证;
3.把void指针转换成目标类型的指针,是及其不安全的;
注:static_cast不能转换掉expression的const、volatile和__unaligned属性。
参考连接数组
int a = 100; double t = static_cast<double>(a) / 6; cout << t << endl; //16.6667
向上转换(好像并非确定安全的记住原始的指针类型 ?):安全
class Base1{ //int a; }; class Base2{ public: int b; }; class Derived: public Base1, public Base2{ }; int main() { int a; void *p; Derived pd; pd.b = 10; cout << pd.b <<endl; cout << "pb: " << &pd<< endl; Base2* pb1 = static_cast<Base2 *>(&pd); cout << pb1->b <<endl; cout << "Derived to Base2: " << pb1 << endl; return 0; } 10 pb: 0x68fefc 10 Derived to Base2: 0x68fefc
使用const_cast去除const限定的目的不是为了修改它的内容,一般是为了函数可以接受这个实际参数ide
const char *cp; char *p = const_cast<char*>(cp);//经过p写值是未定义行为 char *p = static_cast<char*>(cp);//error static_cast<string>(cp); //yes,字符串字面值转变成string(未实践) const int a = 100; int *pA = const_cast<int *>(&a); *pA = 200; int &refA = const_cast<int &>(a); refA = 300; // int *pA1 = static_cast<int *>(&a); Error cout << "*pA:" << *pA << endl;//300 cout << "refA:" << refA << endl;//300 cout << "a:" << a << endl;//100 system("pause");
下面是网上摘录的一段解释:(or常量折叠解释)
const只是告诉编译器不能修改而不是真正地不可修改,若是程序员不注意而去修改了它会报错,如今咱们利用const_cast去除了常量性,而后经过指针和引用对其进行了修改,因此经过指针打印或者引用传参的时候就能看出其内存确实变化了,但为了保护val这个变量原本的const特性,因此每次咱们使用val时,系统都将其替换成初始值100,确保了val仍是“不可变”的
参考博客函数
#include <iostream> using namespace std; void f(int* p) { cout << *p << endl; } int main(void) { const int a = 10; const int* b = &a; // Function f() expects int*, not const int* // f(b); int* c = const_cast<int*>(b); f(c); // Lvalue is const // *b = 20; // Undefined behavior // *c = 30; int a1 = 40; const int* b1 = &a1; int* c1 = const_cast<int*>(b1); // Integer a1, the object referred to by c1, has // not been declared const *c1 = 50; return 0; } http://www.ibm.com/support/knowledgecenter/SS3KZ4_9.0.0/com.ibm.xlcpp9.bg.doc/language_ref/keyword_const_cast.htm
在函数重载上面的应用:spa
const string &shorterString(const string& a, const string& b) { return a.size() <= b.size() ? a : b; } string &shorterString(string& a, string& b) { auto &r = shorterString(const_cast<const string&>(a), const_cast<const string&>(b)); return const_cast<string &>(r); }
能够进行任意之间的转换,不会报错,可是可能破坏程序.net
int *ip; char *pc = reinterpret<char*>(ip); string str(pc); //pc所指真实对象是一个int,因此有问题 与旧式转换相似的功能 int *op; char *p = (char*)op; MSDN上的一个应用- - ,不是很懂reinteroret_cast有什么用 #include <iostream> using namespace std; // Returns a hash code based on an address unsigned short Hash( void *p ) { unsigned int val = reinterpret_cast<unsigned int>( p ); return ( unsigned short )( val ^ (val >> 16)); } using namespace std; int main() { int a[20]; for ( int i = 0; i < 20; i++ ) cout << Hash( a + i ) << endl; }
(想使用基类指针或者引用执行某个派生类非虚函数操做)
dynamic_cast是动态转换,只有在基类指针转换为子类指针时才有意义。(子类指针转换为基类指针原本就是能够的:基类指针指向子类对象OK)。
可是基类指针转换为子类指针,并非每一次都有效:只有基类指针自己指向的是一个派生类的对象,
安全性:
这须要从它的返回值进行讨论,若是符合继承体系且原始指针是指向派生类的对象的,那么返回值将是一个正确的指针值,不然会返回NULL。因此,咱们能够对返回值进行判断来进行判定到底转换是否正确,从而保证程序的健壮性
必须是一个带有虚函数的类。由于dynamic_cast是在对象的内存模型中保存了offset值来实现转换的,这些offset值是保存在虚表(vtbl)中的
虚表参考<Inside c++ object model>:
class MyCompany { public: void payroll(Employee *pe); // }; void MyCompany::payroll(Employee *pe) { Programmer *pm = dynamic_cast<Programmer *>(pe); //若是pe实际指向一个Programmer对象,dynamic_cast成功,而且开始指向Programmer对象起始处 if(pm) { //call Programmer::bonus() } //若是pe不是实际指向Programmer对象,dynamic_cast失败,而且pm = 0 else { //use Employee member functions } } class A { public: virtual ~A(){} //虚函数 多态 }; class B:public A { public: int m; }; A* pObjA = new A(); B* pObjB = NULL; pObjB = dynamic_cast<B*>(pObjA); //编译经过 //实际运行结果:pObjB == NULL // dynamic_cast保证转换无效 返回NULL
来自为知笔记(Wiz)