- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
在提取用于指针运算的原始字节指针时,以下三种类型转换之间有什么区别吗? (假设 char 为 1 个字节的平台。)
static_cast<char*>((void*)ptr))
reinterpret_cast<char*>(ptr)
static_cast<char*>(static_cast<void*>(ptr))
我应该选择哪个?
更详细...
给定一个类中两个成员对象的指针,我想计算一个到另一个的偏移量,这样我就可以在给定偏移量的情况下重建一个成员的地址和另一个成员的地址。
// assumed data layout:
struct C {
// ...
A a;
// ...
B b;
}
我目前使用的代码是这样的:
void approach1( A *pa, B *pb )
{
// compute offset:
std::ptrdiff_t offset = static_cast<char*>((void*)pa) - static_cast<char*>((void*)pb);
// then in some other function...
// given offset and ptr to b, compute ptr to a:
A *a = static_cast<A*>( (void*)(static_cast<char*>((void*)pb) + offset) );
}
main()
{
C c;
approach1(&c.a, &c.b);
}
我想知道以下是更好(还是更差):
void approach2( A *pa, B *pb )
{
std::ptrdiff_t offset = reinterpret_cast<char*>(pa) - reinterpret_cast<char*>(pb);
// ...
A *a = reinterpret_cast<A*>( reinterpret_cast<char*>(pb) + offset );
}
这两种方法是否完全等同?它们是否同样便携?
我的印象是approach1()
更便携,因为“ static_cast
ing a pointer to and from void*
preserves the address ”,而 reinterpret_cast<>
保证更少(请参阅链接中接受的答案)。
我想知道最简洁的方法是什么。
更新:目的说明
很多人问计算这些偏移量的目的是什么。目的是构造一个实例偏移量的元类表。这被运行时反射机制用于自动 GUI 构建和持久化(偏移量未序列化,仅用于遍历结构)。该代码已投入生产超过 15 年。出于这个问题的目的,我只想知道计算指针偏移量的最便携方法。我无意对元类系统的工作方式进行重大更改。此外,我通常也对执行此操作的最佳方法感兴趣,因为我还有其他用途(例如共享内存代码的差异指针)。
注意:我不能使用 offsetof()
因为在我的实际代码中我只有指向实例的指针 a
和 b
, 我不一定有包含对象的类型 c
或其他要使用的静态信息 offsetof()
.我只能假设a
和 b
是同一对象的成员。
最佳答案
这两个将导致相同的结果,所以差异主要是语义上的,reinterpret_cast
具有您想要的操作的确切含义,再加上只需要一次转换而不是两次 (代码中的转换越少越好)。
reinterpret_cast
5.2.10/7: An object pointer can be explicitly converted to an object pointer of a different type. When a prvalue v of object pointer type is converted to the object pointer type “pointer to cv T”, the result is static_cast< cv T* >(static_cast< cv void* >(v)).
因此,除非在中年平台上出现奇特的随机低级不同行为,否则您绝对应该选择:
reinterpret_cast<char*>(ptr);
一般。
就是说,你为什么不使用 uintptr_t在你的情况下?它更合适,你不需要指针:
void approach3( A *pa, B *pb )
{
std::ptrdiff_t offset = reinterpret_cast<std::uintptr_t>(pa) - reinterpret_cast<std::uintptr_t>(pb);
// ...
A *a = reinterpret_cast<A*>( reinterpret_cast<std::uintptr_t>(pb) + offset );
}
有关其他信息,请参阅:
关于c++ - reinterpret_cast<char*>(p) 或 static_cast<char*>((void*)p)) 用于字节指针差异,哪个更好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25638770/
我刚接触 C 语言几周,所以对它还很陌生。 我见过这样的事情 * (variable-name) = -* (variable-name) 在讲义中,但它到底会做什么?它会否定所指向的值吗? 最佳答案
我有一个指向内存地址的void 指针。然后,我做 int 指针 = void 指针 float 指针 = void 指针 然后,取消引用它们以获取值。 { int x = 25; vo
我正在与计算机控制的泵进行一些串行端口通信,我用来通信的 createfile 函数需要将 com 端口名称解析为 wchar_t 指针。 我也在使用 QT 创建一个表单并获取 com 端口名称作为
#include "stdio.h" #include "malloc.h" int main() { char*x=(char*)malloc(1024); *(x+2)=3; --
#include #include main() { int an_int; void *void_pointer = &an_int; double *double_ptr = void
对于每个时间步长,我都有一个二维矩阵 a[ix][iz],ix 从 0 到 nx-1 和 iz 从 0 到 nz-1。 为了组装所有时间步长的矩阵,我定义了一个长度为 nx*nz*nt 的 3D 指针
我有一个函数,它接受一个指向 char ** 的指针并用字符串填充它(我猜是一个字符串数组)。 *list_of_strings* 在函数内部分配内存。 char * *list_of_strings
我试图了解当涉及到字符和字符串时,内存分配是如何工作的。 我知道声明的数组的名称就像指向数组第一个元素的指针,但该数组将驻留在内存的堆栈中。 另一方面,当我们想要使用内存堆时,我们使用 malloc,
我有一个 C 语言的 .DLL 文件。该 DLL 中所有函数所需的主要结构具有以下形式。 typedef struct { char *snsAccessID; char *
指针, C语言的精髓 莫队先咕几天, 容我先讲完树剖 (因为后面树上的东西好多都要用树剖求 LCA). 什么是指针 保存变量地址的变量叫做指针. 这是大概的定义, 但是Defad认为
我得到了以下数组: let arr = [ { children: [ { children: [], current: tru
#include int main(void) { int i; int *ptr = (int *) malloc(5 * sizeof(int)); for (i=0;
我正在编写一个程序,它接受一个三位数整数并将其分成两个整数。 224 将变为 220 和 4。 114 将变为 110 和 4。 基本上,您可以使用模数来完成。我写了我认为应该工作的东西,编译器一直说
好吧,我对 C++ 很陌生,我确定这个问题已经在某个地方得到了回答,而且也很简单,但我似乎找不到答案.... 我有一个自定义数组类,我将其用作练习来尝试了解其工作原理,其定义如下: 标题: class
1) this 指针与其他指针有何不同?据我了解,指针指向堆中的内存。如果有指向它们的指针,这是否意味着对象总是在堆中构造? 2)我们可以在 move 构造函数或 move 赋值中窃取this指针吗?
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: C : pointer to struct in the struct definition 在我的初学者类
我有两个指向指针的结构指针 typedef struct Square { ... ... }Square; Square **s1; //Representing 2D array of say,
变量在内存中是如何定位的?我有这个代码 int w=1; int x=1; int y=1; int z=1; int main(int argc, char** argv) { printf
#include #include main() { char *q[]={"black","white","red"}; printf("%s",*q+3); getch()
我在“C”类中有以下函数 class C { template void Func1(int x); template void Func2(int x); }; template void
我是一名优秀的程序员,十分优秀!