类型转换4大金刚:c++
使用隐式转换和用户定义转换的组合在类型之间进行转换安全
语法:
static_cast < new_type > ( 表达式 )
返回type的值new_type架构
如下总结常使用static_cast的场景函数
//1.initializing conversion int n = static_cast<int>(3.14159); cout << "n = "<<n<<"\n"; //n=3 std::vector<int> v = static_cast<std::vector<int>>(10); cout << "size of v is "<<v.size()<<"\n"; //10
打印值在注释中,经过static_cast将某些类型作“静态”转变后成为咱们但愿的类型,并能正确初始化。this
struct B{ static const int m = 0; void hello() const { cout <<"hello ,this is B"<<"\n"; } }; struct D:B { void hello() const{ cout << "hello,this is D"<<"\n"; } }; //2. static downcast D d; B& br = d; br.hello(); //hello ,this is B D& anther_d = static_cast<D&>(br); anther_d.hello();//hello ,this is D
br经过隐式类型转换后做为d的引用,虽然d是D类型的,可是调用的hello还是B的hello函数,使用static_cast显式downcast后,调用D的hello。这里有一个问题是,hello并非虚函数,即时D继承B,B和D都有一个hello,可是这里的hello函数并非动态绑定的,仍在编译期绑定this的类型。所以br是B类型,而anther_d是D类型的(这里有疑问!!?)
。
若是hello是虚函数,那么怎么解释呢?指针
void* nv = &n; int* ni = static_cast<int*>(nv); std::cout << "*ni = " << *ni << '\n';
这算是static_cast 最经常使用的用法了,经过void指针将类型反转赋值。void能够经过static_cast转变为任意指针类型。code
enum E{ONE = 1,TWO,THREE}; E e = E::ONE; int one = static_cast<int>(e); cout << "one : "<<one <<"\n";
int i = 4; const int& rci = i ; const_cast<int&>(rci) = 8; const int j = 33; int*pj = const_cast<int*>(&j); //DO not use like below ! // *pj = 333; // cout << "const int j = "<< j <<"\n";
struct type{ int i ; type() :i(3){} void f(int v) const{ //if we want to modify i //we cannot use this->i = v; directly; //becuse this pointer is const , //we shall use const_cast this pointer const_cast<type*>(this)->i = v; } }; type t; t.f(40) ; cout << "type i = "<<t.i <<"\n";
使用const修饰的成员函数,咱们将没法经过this指针,修改其成员变量,由于咱们能够将this指针使用const_cast转换为non-const的,只是,你真的肯定要这么作么?!继承
必须是多态场景,存在基类与派生类的类型转换;若是转换成功,dynamic_cast返回类型为new_type的值。若是转换失败,而new_type是指针类型,则返回该类型的空指针。若是转换失败,而且new_type是引用类型,它将抛出一个异常,该异常与类型std::bad_cast的处理程序匹配。内存
struct Base { virtual ~Base() {} }; struct Derived: Base { virtual void name() {} }; void testDynamic_cast() { Base *b1 = new Base; if(Derived*d = dynamic_cast<Derived*>(b1)){ cout << "downcast from b1 to d successful\n"; d->name(); } Base *b2 = new Derived; if(Derived*d = dynamic_cast<Derived*>(b2)){ cout << "downcast from b2 to d successful\n"; d->name(); } delete b1; delete b2; }
输出
downcast from b2 to d successful
ci
可见b1的dynamic_cast转换是失败的。缘由是显而易见的 ,此时的b1指针并无指向其派生类,天然不能进行动态转换。可是,在C类型的转换中,这样的转换是没有任何提示和预见性的,因此,C类型的转换应该被全线禁止掉。
标准文档上的解释是:经过从新解释底层位模式在类型之间进行转换
与static_cast不一样,但与const_cast类似,reinterpret_cast表达式不会编译成任何CPU指令(除非在整数和指针之间进行转换,或者在指针表示依赖于其类型的模糊架构上进行转换)。
它纯粹是一个编译时指令,指示编译器将表达式视为具备new_type类型
unsigned int i = 0x12345678; char* p1 = reinterpret_cast<char*>(&i); if(p1[0] == '\x78') cout << "This system is little-endian\n"; else cout << "This system is big-endian\n";
p1指针将i的地址重现解释为char*类型。这里顺便复习下大小端的知识,78是i的低字节位,若是它位于unsigned int内存的低地址区域则说明系统为小端,不然为大端。
以上,说明了四种C++类型转换表达式的使用场景,按我我的理解小结下: