C++的强制类型转换
static_cast
static_cast用于非多态类型的转换(静态转换),任何标准转换都可以用它,但它不能用于两个不相关的类型进行转换.
何为不相关类型? 比如int 和 double char short就是相关类型. 和int*就是不相关类型.
我们来看一看static_cast的用法. 例如,通过将一个运算对象强制转换成double类型就能使表达式执行浮点数除法:
double slope = static_cast<double>(j) / i;
当static_cast需要把一个较大的算术类型赋值给较小的类型时,static_cast非常有用。此时,强制类型转换告诉程序
的读者和编译器:我们知道并且不在乎潜在的精度损失。一般来说,如果编译器发现一个的算术类型试图赋值给较小的
类型,就会给出警告信息;但是当我们执行了显式的类型转换后,警告信息就会被关闭了。
reinterpret_cast
typedef void (* FUNC)();
int DoSomething (int i)
{
cout<<"DoSomething" <<endl;
return 0;
}
void Test ()
{
// reinterpret_cast可以编译器以FUNC的定义方式去看待 DoSomething函数
// 所以非常的BUG,下面转换函数指针的代码是不可移植的,所以不建议这样用
// C++不保证所有的函数指针都被一样的使用,所以这样用有时会产生不确定的结果
FUNC f = reinterpret_cast< FUNC>(DoSomething );
f();
}
const_cast
#include<iostream>
#include<Windows.h>
#include<assert.h>
using namespace std;
int main()
{
const int a = 2;
int *p = const_cast<int*>(&a);
*p = 3;
cout << a << endl;
system("pause");
return 0;
}
这不科学啊?? 我们再打开监视窗口看一下a的值.
#include<iostream>
#include<Windows.h>
#include<assert.h>
using namespace std;
int main()
{
volatile const int a = 2;
int *p = const_cast<int*>(&a);
*p = 3;
cout << a << endl;
system("pause");
return 0;
}
dynamic_cast
前三种的强制类型转换,他们能做到的C语言的强制类型转换也大多能做到,最后一种C语言的强制类型转换就没
有办法了.在类的转换时,在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的。在进行下
行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。当用于多态类型时,它允许任意的隐式类
型转换以及相反过程. 不过,与static_cast不同,在后一种情况里(注:即隐式转换的相反过程),dynamic_cast
会检查操作是否有效. 也就是说, 它会检查转换是否会返回一个被请求的有效的完整对象。检测在运行时进行.
如果被转换的指针不是一个被请求的有效完整的对象指针,返回值为NULL. 对于引用 类型,会抛出bad_cast异常
你说这个强转有啥用,其实对于我这种菜鸟还真的没用过,不过我知道一个问题可以使用这样的方法解决. 给你两
个类让你分辨那个是子类那个是父类,我们来看看是如何解决的.
#include<iostream>
#include<Windows.h>
#include<assert.h>
using namespace std;
class AA
{
public:
virtual void fun1()
{
cout << "hehe" << endl;
}
public:
int a;
};
class BB :public AA
{
public:
virtual void fun1()
{
cout << "heh2e" << endl;
}
public:
int c;
};
int main()
{
AA* q = new AA();
BB* p = new BB();
AA* a;
BB* b;
b = dynamic_cast<BB*>(q);
if (b == NULL)
{
cout << "AA为基类" << endl;
}
else{
cout << "AA为子类" << endl;
}
a = dynamic_cast<AA*>(p);
if (a == NULL)
{
cout << "BB为基类" << endl;
}
else
{
cout << "BB为子类" << endl;
}
system("pause");
return 0;
}