简体   繁体   English

我可以使用 C++ 中的成员变量地址获得 object 的引用吗?

[英]Can I get reference of an object with address of member variable in C++?

Is it possible to get a reference to an object if I have only the address of a member variable of that object?如果我只有 object 的成员变量的地址,是否可以获得对 object 的引用?

class example{
    public:
        int var;
};


int main(){
    
    example exampleObject;
    
    int* point=&exampleObject.var;
    
    example* objPointer; // can i get objPointer to point to exampleObject only using point
    return 1;
}

Can I get reference of an object with address of variable in C++?我可以在 C++ 中获取带有变量地址的 object 的引用吗?

Based on the example code, there appears to be a crucial word missing from this qustion.根据示例代码,此问题中似乎缺少一个关键词。 It appears that you want to get reference to an object with an address of a member variable of that object, rather than a variable of the class type.您似乎希望使用 object 的成员变量的地址而不是 class 类型的变量来引用 object。

Potentially yes, but there are limitations.可能是的,但有一些限制。

Only if the class in question is a standard layout class is this possible.只有当所讨论的 class 是标准布局 class 时才有可能。 In that case, you can reinterpret a pointer to the first member as a pointer to the class itself.在这种情况下,您可以将指向第一个成员的指针重新解释为指向 class 本身的指针。 You can then indirect through the pointer to get a reference:然后可以通过指针间接获取引用:

static_assert(std::is_standard_layout_v<example>);
example* objPointer = reinterpret_cast<example*>(point);
assert(objPointer == &exampleObject); // guaranteed to pass

Getting pointer to a standard layout class based on a member other than the first may be possible using the offsetof macro, although all attempts to implement that idea that I've seen rely on something that is either technically undefined behaviour, or at least implementation defined.使用offsetof宏可以获得基于除第一个成员以外的成员的标准布局 class 的指针,尽管我所看到的实现该想法的所有尝试都依赖于技术上未定义的行为,或者至少是实现定义的东西.

Here is the implementation from the Linux kernel (not written in C++, but C, which may be more relaxed in what is allowed): Here is the implementation from the Linux kernel (not written in C++, but C, which may be more relaxed in what is allowed):

 #define container_of(ptr, type, member) ({ \ const typeof(((type *)0)->member) * __mptr = (ptr); \ (type *)((char *)__mptr - offsetof(type, member)); })

typeof is not in standard C++, nor even in standard C, but is a GNU language extension. typeof不在标准 C++ 中,甚至不在标准 C 中,而是 GNU 语言扩展。 This also uses a statement expression (not to be confused with expression statements), which is another GNU extension.这也使用了一个语句表达式(不要与表达式语句混淆),这是另一个 GNU 扩展。

Alert : don't do it regularly since it's very easy to mess thing out警告:不要经常这样做,因为这很容易把事情搞砸

#include <iostream>

class example{
public:
    int var;
};


int main(){

    example exampleObject{15};

    int* point=&exampleObject.var;

    example* objPointer = reinterpret_cast<example*>(point);
    std::cout << objPointer->var;
    return 0;
}

now objPointer will points to the original object, however this works only because of how object are managed, and so because since var is the first property of a class without a base class, its address will be the same of the object, but if you have something like this: now objPointer will points to the original object, however this works only because of how object are managed, and so because since var is the first property of a class without a base class, its address will be the same of the object, but if you有这样的东西:

class example{
public:
    int var;
    int var2;
};


int main(){

    example exampleObject{15, 16};

    int* point=&exampleObject.var2;

    example* objPointer = reinterpret_cast<example*>(point);
    std::cout << objPointer->var2;
    return 1;
}

It won't work, because var2 is not saved in the same address where the object is saved, since there is var saved before it它不起作用,因为var2没有保存在保存 object 的同一地址中,因为在它之前保存了var

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM