Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从成员指针获取类/结构对象 < >我的C++结构为 struct myStruct { int a; int b; int c; }; myStruct b; int *ptr = &b.c;_C++ - Fatal编程技术网

从成员指针获取类/结构对象 < >我的C++结构为 struct myStruct { int a; int b; int c; }; myStruct b; int *ptr = &b.c;

从成员指针获取类/结构对象 < >我的C++结构为 struct myStruct { int a; int b; int c; }; myStruct b; int *ptr = &b.c;,c++,C++,如何从ptr获取myStruct对象 (我知道我可以使用C中的类似container_Of()的指针算法来实现这一点 reinterpret_cast<myStruct*>(reinterpret_cast<char *>(ptr) - offsetof(myStruct, c)); reinterpret_cast(reinterpret_cast(ptr)-offsetof(myStruct,c)); 我问是否有推荐的/优雅的方式?< p>当然没有推荐的方法,因为

如何从ptr获取myStruct对象

(我知道我可以使用C中的类似container_Of()的指针算法来实现这一点

reinterpret_cast<myStruct*>(reinterpret_cast<char *>(ptr) - offsetof(myStruct, c));
reinterpret_cast(reinterpret_cast(ptr)-offsetof(myStruct,c));

<>我问是否有推荐的/优雅的方式?

< p>当然没有推荐的方法,因为在C++中绝对不推荐这样做。这是一个正确答案必须是“不要那样做”的问题

<> P>使用C++代替C的全部原因是,你要把数据结构封装在它们上面定义的有意义操作的类内,而不是让整个程序知道数据结构的内部布局。
也就是说,您描述的
偏移
技术将适用于普通的旧数据对象,因为它们与C结构没有什么不同。

因为ptr不知道它的覆盖结构,我认为没有一种优雅的方式返回到myStruct
我只是建议不要这样做

您的
重新解释\u cast
解决方案是实现您想要的标准方法。它必须至少涉及一个强制转换的原因是您要执行的操作本质上是不安全的。显然,并非所有指向
int
的指针都指向
myStruct
的第三个成员,因此不可能有简单的类型安全方式来执行转换。

您的文本和示例使用POD结构;然而,你的标题也谈到了课程。下面的答案不适用于非POD类型

对于吊舱类型,请查看


找到偏移量,使用&pointer算法备份,比如说一个char*基。

你可以使用这样一个事实,当你从一个指针转换到一个基类时,它不是唯一的基类,编译器会调整指针,使它指向超类的开始。因此,如果您的“c”成员存在于某个基类的开头,您可以执行如下操作:

struct myStructBase1 { int a; };
struct myStructBase2 { int b; };
struct myStructBase3 { int c; };

struct myStruct : public myStructBase1,myStructBase2,myStructBase3 {
    int d;
};

int main() {
    myStruct my;

    int * bptr = &my.b;
    int * cptr = &my.c;
    // The only dirty part in the code...
    myStructBase2 * base2ptr = reinterpret_cast<myStructBase2*> (bptr);
    myStructBase3 * base3ptr = reinterpret_cast<myStructBase3*> (cptr);

    // In each (myStruct*) cast the pointers are adjusted to point to the super class.
    cout << &my << endl <<
            (myStruct*) base2ptr << endl <<
            (myStruct*) base3ptr << endl;
    return 0;
}
// Output:
// 0xbfbc779c
// 0xbfbc779c
// 0xbfbc779c
输出为:

0xbfa305f4
0xbfa305f8
0xbfa305f4

对于c成员,约束仍然有效。因此,一般来说,答案是:是的,有另一种方法。然而,为每个“可逆”成员定义一个基类可能不是明智的方法。但这是一个wierd逻辑,必须使用C库中的某些东西并注册回调。如果我定义一个只有几个功能的结构(没有派生的结构等),它还会被算作POD吗?只要没有虚拟功能,是的,但它甚至不接近便携。是的。C++编译器只是将成员函数生成为普通函数(只是链接器的奇怪名称和传递‘这个’指针值的某种方式),而结构体在内存中的布局就像在C.中一样,但是在任何情况下,如果调用的C库允许您通过一个不透明指针来回调,你可以把你喜欢的任何东西的地址传给它。如果它需要函数指针,可以将静态成员函数的地址传递给它。但是,你可以把它传递给整个类对象(它怎么知道?)C++中的类和结构之间有区别,除了默认声明中的一个是私有的,另一个是公共的。
0xbfa305f4
0xbfa305f8
0xbfa305f4