C++学习笔记 33 类型双关(直接读取内存)
一、什么是类型双关?
类型双关是一个花哨的术语,用来在C++中绕过类型系统。我要把我拥有的这段内存,当做不同类型的内存来对待。我们只需要将该类型作为指针,然后将其转换为另一个类型的指针。有必要的话,还可以进行解引用。
C++是强类型语言,它有一套类型系统(并不是所有的东西都用auto去声明,可以用auto,但毕竟它也是一个关键字),像double、float、char等。然而这种类型系统并不像java语言那样强制,包括C#也是,你虽然也可以绕开类型系统,但要做更多的工作。但是在其它语言,像JavaScript,没有变量类型的概念,在创建变量时,不需要声明变量类型,当我们接受它作为函数的参数时,并没有一个类型,但是C++有一个类型系统。
在C++中,虽然类型是由编译器强制执行的,但你也可以直接访问内存。这意味着,在代码中,我们可以以double或struct的形式读取int类型数据内存。
你可以很容易地绕过类型系统。是否需要用,取决于你的实际情况。在某些情况下,绝对不应该规避类型系统,因为类型系统存在是有原因的。除非你有充分的理由,否则你可能不想过多地使用它。
但在其他情况下,这样做是完全可以的。例如,假设我们有一个类,我们想把它写成一个字节流,不需要很麻烦。假设它是一个基本类型的结构,并且没有指向内存中其他地方的指针,那么我们就可以重新解释整个结构或类等等,将它作为一个字节数组,然后将它写出来或者流出来(字节流)。我们不需要关心里面是什么类型,只需要知道数据访问的大小,然后把它放到某个地方即可。
在很多情况下,它是非常有用的。这是一种原始的、底层的访问。这就是为什么我喜欢C++,以及C++效率这么高,应用程序性能这么好的原因了。
C++ 很擅长搞这个,这也就是为什么说C++是非常强力的语言,它是一种强大的语言的一个重要原因是,它可以很容易地自如地操纵内存。
#include<iostream>
//占用内存是连续的,只用来存储 x, y
struct Entity {
int x, y;
};
int main() {
//强制类型转换
int intA = 50;
//隐式
double db = intA;
//显式
double db = (double)intA;
std::cout << db << std::endl;
//类型双关1:从int 到 double
//int : 4字节
int a = 50;
//double : 8字节
double b = *(double*)&a;
//将a和a后面的另外4字节数据取出,类型输出为:double,然后解引用为一个数据(不确定是什么数据了)。
std::cout << b << std::endl;
//类型双关2
Entity entity = { 5, 8 };
int* position = (int*)&entity;
std::cout << position[0] << " | " << position[1] << std::endl;
//类型双关3
int y = *(int*)((char*)&entity + 4);
std::cout << y << std::endl;
std::cin.get();
}

浙公网安备 33010602011771号