您的位置:首页 > 编程语言 > C语言/C++

C++的四种强制类型转换

2016-07-14 14:07 387 查看
C++的四种强制类型转换

C++的四种强制类型转换分别为:static_cast ,const_cast

, reinterpret_cast, dynamic_cast 

新类型的强制转换可以提供更好的控制强制转换过程,允许控制各种不同种类的强制转换。C++中风格是 static_cast<type>(content)。C++风格的强制转换其他的好处是,它们能更清晰的表明它们要干什么。

1,static_cast:可以实现C++中内置基本数据类型之间的相互转换。

eg: int c=static_cast<int>(7.987);

如果涉及到类的话,static_cast只能在有相互联系的类型中进行相互转换,不一定包含虚函数。

#include<iostream>
#include<string>
using namespace std;
class A
{
public: A()
{
cout << "Inside class A " << endl;
double a = 9.8831;
int i = static_cast<int>(a);
cout << "i = " << i << endl;
}
void Test()
{
cout << "Inside class A   Test() " << endl;
char c = 'C';
int j = static_cast<int>(c);
cout << "j = " << j << endl;
}
};

class B : public A
{
public:B()
{

}
B(const A* )
{

}
};

class C
{
public:C()
{
cout << "Inside classC " << endl;
}

};

int main()
{
A* a = new A;

B* b;
C* c;

b = static_cast<B*> (a); //// 编译不会报错, B类继承A类
b->Test();

//	c = static_cast<B*>(a);	// // 编译报错, C类与A类没有任何关系

return 0;
}
2,const_cast: const_cast操作不能在不同的种类间转换。相反,它仅仅把一个它作用的表达式转换成常量。它可以使一个本来不是const类型的数据转换成const类型的,或者把const属性去掉。

也就是说,const_cast常量指针被转化成非常量指针,并且仍然指向原来的对象;常量引用被转换成非常量引用,并且仍然指向原来的对象。
#include<iostream>
using namespace std;

int main()
{
int i = 10;
const int &j = i;

cout << "Before cosnt_cast. j = " << j << endl;
//	j = 30; //error
int &k = const_cast<int&>(j);
k = 20;
cout << "After const_cast.  k = " <<k<< endl;

return 0;
}


3,reinterpret_cast: 
用来处理无关类型之间的转换;它会产生一个新的值,这个值会有与原始参数(expressoin)有完全相同的比特位。

通常用于指针类型间的强制转换,或用于整数和指针类型间的强制转换。

#include<iostream>
using namespace std;

int main()
{
int i = 0;

int* j = reinterpret_cast<int*>(i);

if(NULL == j)
{
cout << "reterpret_cast successfully j = 0" << endl;
}
else
{
cout << "reterpret_cast failed j != 0" << endl;
}

return 0;
}


4,dynamic_cast: 

(1)其他三种都是编译时完成的,dynamic_cast是运行时处理的,运行时要进行类型检查。

(2)不能用于内置的基本数据类型的强制转换。

(3)dynamic_cast转换如果成功的话返回的是指向类的指针或引用,转换失败的话则会返回NULL。

(4)使用dynamic_cast进行转换的,基类中一定要有虚函数,否则编译不通过。

     B中需要检测有虚函数的原因

        这是由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表(关于虚函数表的概念,详细可见<Inside c++ object model>)中,

        只有定义了虚函数的类才有虚函数表。

(5)在类的转换时,在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的。在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。向上转换即为指向子类对象的向下转换,即将父类指针转化子类指针。向下转换的成功与否还与将要转换的类型有关,即要转换的指针指向的对象的实际类型与转换以后的对象类型一定要相同,否则转换失败。

(6)dynamic_cast
用于有继承关系的类指针间的转换,用于有交叉关系的类指针间的转换。

#include<iostream>
#include<cstring>
using namespace std;

class A
{
public:
virtual void func_1()
{
cout << "class A_func_1()" << endl;
}
};

class B: public A
{
public:
void func_2()
{
cout << "class B_func_2()" << endl;
}
};

class C
{
public:
void func_3()
{
cout << "class C_func_3()" << endl;
}
};

int fun()
{
cout << "int fun()" << endl;
}
int main()
{
A* a1 = new B;  //a1是A类型的指针指向一个B类型的对象
A* a2 = new A; //a2是A类型的指针指向一个A类型的对象
B* b;
C* c;

b = dynamic_cast<B*>(a1);
//结果为not null,向下转换成功
//a1之前指向的就是B类型的对象
//所以可以转换成B类型的指针。

if(NULL != b)
{
cout << "first time b != NULL, successful convert" << endl;
}
else
{
cout << "first time b == NULL,  convert failed" << endl;
}

b = dynamic_cast<B*>(a2);  //向下转换,子类指针转为父类指针
//要转换的指针指向的对象的实际类型与转换以后的对象类型一定要相同,
//否则转换失败。
//如果是
//a1 = dynamic_cast<B*>(a2);
//就可以成功,因为指针指向的实际类型相同(都是A类型)
if(NULL != b)
{
cout << "second time b != NULL, successful convert" << endl;
}
else
{
cout << "second time b == NULL,  convert failed" << endl;
}

c = dynamic_cast<C*>(a1); //没有继承关系
if(NULL != b)
{
cout << "third time c != NULL, successful convert" << endl;
}
else
{
cout << "third time c == NULL,  convert failed" << endl;
}

delete (a1);
delete (a2);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: