我一直在努力研究类型转换和类型转换之间的区别。 我学到的是,当一种类型的基础值或位表示形式被更改为另一个值时,我们已经执行了一个转换。 而在纯类型强制转换中,我们只是告诉编译器将位模式视为另一种类型。 我使用“pure”是因为强制转换可能导致转换,在这种情况下,它被称为“显式转换”。
我想到了两个例子来说明这种区别。 第一:
float x = 1.5;
float* p1 = &x;
int* p2 = (int*) p1;
int i = *p2;
在这里,强制转换指针类型不对指针值执行任何操作。 所以这是纯粹的选角。 在本例中,它导致了未定义的行为,因为我们基于F1.5的位表示(准确地说是1069547520)获得int值。
第二:
B* b = new D();
D* d = static_cast<D*>(b);
其中D是从B导出的。在第一行中进行隐式转换。 在第二行中,强制转换实际上也是一种转换,这些转换是因为指针值可能会改变,如果需要的话,可以调整值以指向完整的D对象或B子对象(我还不完全理解偏移是如何工作的)
我对用户定义的类转换调用指针强制转换是否正确? 如果是这样,那么上面的static_cast也执行了一个转换(显式),而我读到的这个答案调用了一个完全不同的概念:
https://stackoverflow.com/A/34268988/1219638-
标准转换是具有内置含义的隐式转换,与static_cast或C样式转换是不同的概念。
还有,为什么用户定义的类指针的转换被称为标准转换?
我能问最后一个问题吗? 我已经了解到,当类型相关时,C样式的强制转换会像static_cast一样。 这是否意味着C样式的强制转换在必要时也会计算偏移量?
重要的是要理解,就C++语言而言,您所说的区别并不存在。 所有“*_cast
s”(以及它们的C等价物)都只是(显式)转换。 并且对于语言,所有转换都创建一个新对象(如果转换为引用类型,则创建对现有对象的新引用)。
指针是对象。 int*p2=(int*)p1;
执行一个reinterpret_cast
,它创建一个不同类型的新指针对象。 p2
是与p1
截然不同的对象,即使它们指向相同的内存。 如果您执行了++p2
,那将不会影响p1
的指向。
因此,从语言的角度来看,强制转换只是某些显式转换,这些转换使用了包含“cast”一词的语法(或与包含“cast”一词的语法等价的语法)。
您要做的区别基本上是转换返回的值是与原始对象相同的二进制值,而返回的值不是二进制值。 好吧,C++并不真正关心; 所有(非引用)转换都返回一个新对象。 C++既没有也不需要术语来描述新对象与旧对象相同时的转换。 而且有许多“*_cast
”操作可能不会返回二进制相同的值,因此即使希望创建这样一个概念,将其称为“强制转换”也会令人困惑。
还有,为什么用户定义的类指针的转换被称为标准转换?
因为C++标准就是这么称呼它们的。 我的意思并不是说我们称它们为“标准”,因为它们是C++标准的。 我的意思是,C++标准有一个叫做“标准转换”的概念,某些类型的指向类的指针之间的转换是其中的一部分。
“标准转换”是一种可以隐式发生的转换(即:在转换的位置没有专门的语法)。 指向派生类的指针可以隐式转换为指向可访问基类的指针。 这是多态继承功能的一部分:某些代码可以作用于派生类实例,而不知道具体作用于哪个类型。 多态基类提供了一个编写代码要使用的通用接口,派生的类提供了该接口的各种实现。
我一直在努力研究类型转换和类型转换之间的区别。
区别如下:
在这种情况下,它导致了未定义行为
正确。
因为我们得到的int值是基于F1.5的位表示,准确地说是1069547520。
注意,由于行为是未定义的,我们不能保证得到精确的值。 程序的行为可以是任何东西; 它可能崩溃,无法构建,行为完全按照你想要的,甚至行为完全按照你不想要的方式。
我对用户定义的类转换调用指针强制转换是否正确?
调用强制转换是很常见的。 虽然从技术上说,强制转换导致转换可能更为准确。
如果是,那么上面的static_cast也执行了转换(显式)
正确。
还有,为什么用户定义的类指针的转换被称为标准转换?
因为它是一个指针,而指针之间的转换是标准转换。
这是否意味着C样式的强制转换在必要时也会计算偏移量?
是的。 如果静态强制转换必须计算偏移量,而C样式强制转换执行静态强制转换,则C样式强制转换计算偏移量。
附注。 不要使用C型造型。