uni*_*eid 2 c++ pointers casting
我一直试图围绕类型转换和类型转换之间的差异进行思考。我学到的是,基本上当一种类型的基础值或位表示更改为另一种值时,我们已经执行了转换。而在纯类型转换中,我们只是告诉编译器将位模式视为另一种类型。我使用“纯”是因为转换可能会导致转换,在这种情况下它被称为“显式转换”。
我想到了两个例子来说明这种差异。第一的:
float x = 1.5;
float* p1 = &x;
int* p2 = (int*) p1;
int i = *p2;
Run Code Online (Sandbox Code Playgroud)
这里转换指针类型不对指针值执行任何操作。所以它是纯铸造。在这种情况下,它会导致未定义的行为,因为我们根据 f1.5 的位表示获得 int 值,准确地说是 1069547520。
第二:
B* b = new D();
D* d = static_cast<D*>(b);
Run Code Online (Sandbox Code Playgroud)
其中 D 派生自 B。这里的第一行进行了隐式转换。在第二行中,转换实际上是一个转换。这些是转换,因为指针值可能会改变,如果需要调整值以指向完整的 D 对象或 B 子对象(我还没有完全理解偏移是如何工作的尽管。)
我在调用用户定义类转换的指针转换时是否正确?如果是这样,那么上面的 static_cast 也执行了转换(明确地),而我读到的这个答案调用完全不同的概念:
标准转换是具有内置含义的隐式转换,并且是独立于 static_cast 或 C 样式转换之类的概念。
另外为什么用户定义的类指针的转换称为标准转换?
我可以问最后一个问题吗?我了解到,当类型相关时,C 风格的强制转换将像 static_cast 一样。这是否意味着 C 风格的强制转换也将在必要时计算偏移量?
重要的是要了解,就 C++ 语言而言,您所谈论的区别并不存在。所有“ *_casts”(以及它们的 C 等价物)都只是(显式)转换。对于语言,所有转换都会创建一个新对象(如果转换是引用类型,则创建一个对现有对象的新引用)。
指针是对象。int* p2 = (int*) p1;执行 a reinterpret_cast,它创建一个不同类型的新指针对象。p2是与 不同的对象p1,即使它们指向相同的内存。如果您这样做了++p2,那绝不会影响p1指向的内容。
因此,从语言的角度来看,强制转换只是某些显式转换,它们使用包含“cast”一词的语法(或与包含“cast”一词的语法等效的语法)。
您试图做出的区别基本上是转换返回与原始对象二进制相同的值,而当它不返回时。好吧,C++ 并不真正关心;所有(非引用)转换都返回一个新对象。当新对象与旧对象二进制相同时,C++ 既没有也不需要术语来描述转换。并且有很多 " *_cast" 操作可能不会返回二进制相同的值,因此即使人们希望创建这样的概念,将其称为“强制转换”也会令人困惑。
另外为什么用户定义的类指针的转换称为标准转换?
因为这就是 C++ 标准对它们的称呼。我并不是说我们称它们为“标准”,因为它们属于 C++ 标准。我的意思是 C++ 标准有一个称为“标准转换”的概念,某些类型的类指针之间的转换是其中的一部分。
“标准转换”是一种可以隐式发生的转换(即:在转换站点没有专门的语法)。指向派生类的指针可以隐式转换为指向可访问基类的指针。这是多态继承的一部分:某些代码可以在不知道它正在作用于哪种类型的情况下作用于派生类实例的能力。多态基类提供了编写代码使用的通用接口,派生类提供了该接口的各种实现。
| 归档时间: |
|
| 查看次数: |
166 次 |
| 最近记录: |