C/C++类型转换
C风格类型转换
C语言中的类型转换, 实际上强迫编译器根据程序员的选择来解释目标.
int main()
{
char buffer[20] = {"hello"};
int *a = (int*)buffer;
int b = (int)buffer;
}
C语言中仅需在变量前用括号指明类型, 即可进行类型转换; 编译器不会报错. 在C++中其实也提供了对于C的兼容, 但是这种强制的类型转换破坏了类型安全.
C++风格的类型转换
static_cast
dynamic_cast
reinterpret_cast
const_cast
在C++中类似C风格的类型转换开始有了一些限制,取而代之的是一些显式的运算符进行配置转换
static_cast
- 用于相关类型的指针转换
- 显示执行标准数据类型的转换
#include <stdio.h>
#include <stdlib.h>
class Parent
{
};
class Son: public Parent
{
};
class Exp
{
public:
explicit Exp(int a){}
};
int main()
{
double a = 4.55;
int b = a;
int c = static_cast<int>(b);
Parent *p = new Parent;
Son *s = new Son;
Parent *p1 = s;
//Son *s1 = p; -error
Son *s1 = static_cast<Son*>(p);
//Exp e1 = 1; --error
Exp e2 = static_cast<Exp>(1);
}
- 普通数据类型的转换, 该运算符并没有什么意义; 仅是为了显示说明
- 子类指针可以转换为父类, 反之不可以(子类包含父类和子类本身的数据); 使用
static_cast
可以将父类转为子类, 但是在运行中可能出现问题. - 当禁止了隐式类型转换时, 可以使用该运算符显示的说明
dynamic_cast
与static_cast不同的是提供动态的
类型检测
, 可以通过判断转换的结果以判断类型转换是否成功.
#include <stdio.h>
#include <stdlib.h>
class Parent
{
public:
virtual void tt(){};
};
class Son: public Parent
{
};
void fun(Parent* p)
{
Son *s = dynamic_cast<Son*>(p);
if(s)
{
printf("%s\n", "this is a son calss!");
}
else
{
printf("%s\n", "this is not a son class!");
}
}
int main()
{
Parent *a = new Parent;
Son *b = new Son();
fun(a);
fun(b);
}
//结果
this is not a son class!
this is a son calss!
:
- 需要转换的类型必须是多态的的, 即需要有一个虚函数; 据此推断其应当是通过虚函数表来说进行比对判断的。
- 结果是有可能为NULL的, 该运算符应当用于判断而不是单纯的类型转换
reinterpret_cast
提供类似C风格的类型转换, 同样并未修改二进制数据;
int main()
{
char buffer[20] = {"hello"};
int a = (int)buffer;
int b = reinterpret_cast<int>(buffer);
//int c = static_int<int>(buffer); --error
//int d = dynamic_cast<int>(buffer); --error
printf("%s\n", (char*)b); //可以继续使用
}
const_cast
关闭对象的
const
描述符.
#include <stdio.h>
#include <stdlib.h>
class Parent
{
public:
int a;
Parent(int _a):a(_a){};
};
int main()
{
const Parent p(10);
//p.a = 10; error
Parent &pp = const_cast<Parent&>(p);
pp.a = 20;
}
:
上述用法虽然可行, 但是应当坚决禁止使用; 当使用第三方库时可能遭遇到参数传递的问题, 可以使用该方法修改; 如果希望以此来进行参数更改或实现功能, 应当禁止.
C++中类的配置转换重载
class Test_Class_A {
public:
operator int ()
{
return 100;
};
};
int main() {
Test_Class_A tca;
printf("%d\n", (int)tca);
printf("%d\n", static_cast<int>(tca));
return 0;
}
在C++中的引入的配置转换重载,是支持()
转换和static_cast
转换两种操作的;如果不支持这种转换,会直接报错。
网友评论