当前位置: 首页 > 知识库问答 >
问题:

获取包含成员子对象的完整对象的地址

萧业
2023-03-14

我有两个类,大致定义如下:

class Inner {
public:
  bool is_first;
};

class Outer {
public:
  char some_other_member;
  Inner first;
  Inner second;
}

我知道内层只存在于外层中,并且当且仅当相应对象是第一个成员,而不是第二个时,相应的bool标志将设置为true

我正在寻找一种符合标准的方法来派生指向包含一些内部对象的Outer对象的指针。当然,我可以只在每个Inner对象中存储一个指针,但由于Inner类非常小,而且我有很多,这似乎是浪费内存(因此也是宝贵的缓存)。

显然,编译器应该知道firstfirst和包含的外部对象之间的内存偏移量。问题是:是否有一种符合标准的方法告诉编译器“获取该偏移量,将其从指向内部的指针中减去,并使其成为外部指针”?

我知道如果Outer将包含Inners作为基本子对象(例如,这个),我可以使用强制转换来 -我觉得成员子对象应该可以有类似的功能?

共有3个答案

寿伟
2023-03-14

这就是offsetof的作用。

像这样的东西:

Outer *Inner::getOuter() {
    size_t offset = flag ? offsetof(Outer, first) : offsetof(Outer, second);
    return reinterpret_cast<Outer *>(
        reinterpret_cast<char *>(this) - offset);
}

请注意,您正在重新解释广播,因此您完全有责任知道自己在做什么。如果标志不同步,您将得到未定义的行为。

请注意,指针算法只允许在数组中使用,但是6.9/4 ([basic.types])明确指出每个对象都存储在这样一个< code>unsigned char数组中:

T 类型的对象的对象表示是 T 类型的对象所占用的 N 个无符号 char 对象的序列,其中 N 等于大小(T)

在这个数组中,定义了指针算法。但你需要确保你确实在分配范围内。

廖令
2023-03-14

没有严格正确的解决方案,你会碰到一些指针算术规则。然而,有一个实现定义的解决方案,它几乎总是做您期望它做的事情

auto get_outer(Inner& i)
{
    return (Inner*)(((uintptr_t)&i) - offsetof(Outer, first));
}

catch是指针和整型转换是由实现定义的。

邓兴为
2023-03-14

您应该注意,从指向成员的指针获取指向父对象的指针的问题通常是无法解决的。

偏移和强制转换仅适用于标准布局类型。在其他情况下,这是未定义的行为。

例如,对于多重虚拟继承,它会失败。在这种情况下,成员访问是通过比添加编译时偏移量更复杂的方式实现的。也许这实际上并不相关,因为它很少被使用,但是您明确地要求符合标准。

 类似资料:
  • 我有非常复杂的冬眠结构,有许多@manytomy、@ManyToOne、@OneToOne等关联。这些嵌套的集合/对象也有自己的嵌套对象/集合。整个对象被延迟加载。 我试图实现的是,对于一个特定的操作,能够急切地获取整个对象。 我做了一些研究,但我所能找到的只是需要指定每个对象/集合并手动获取的解决方案。 有没有一种方法可以获取整个对象结构,而无需指定需要获取的每个对象?

  • 然后是班级选拔: 教材: 因此,我主要创建新用户并将其序列化: 一切都很完美,但如果我这样做: 然后我想序列化对象用户,程序崩溃了。我得到的结果是: JAVA木卫一。NotSerializableException:在java上。木卫一。ObjectOutputStream。java上的WriteObject 0(ObjectOutputStream.java:1183)。木卫一。ObjectOu

  • 我从accuweather获得了以下带有json的代码 我尝试通过Jackson将此对象解析为POJO 我有json中指定的所有模型,如、数组、,由组成(在json中命名为最小值和最大值)等,它们都有私有字段和公共构造函数、getter和setter。但是我没有一些字段,因为我想省略它们(Day、night、EpochDate、Source)。 当我运行程序时,我得到了错误 com.fasterx

  • 2个问题: > < li> 以下代码是否符合定义的行为? 是否有任何可能的c实现可以断言? 代码(c 11 及更高版本): 请注意, 和 具有不同的访问说明符。

  • 我正在使用和。 我正在努力获取子对象的子对象来填充。下面是我的课。 应用程序类; 子类: ChildRelationshipType类: 存储库中GetAll方法的一部分,以返回所有应用程序: 子类包含对ChildRelationshipType类的引用。要处理应用程序的子级,我需要这样做: 我在这里得到一个错误,即对象上下文已经关闭。 如何指定每个子对象必须包括对象,就像我上面所做的那样?

  • 问题内容: 有没有办法获取Java对象的地址? 问题来自哪里?:首先,我读取属性文件,并将文件中的所有数据放入表中。属性文件可以更新。所以,我想听那个文件。我使用PropertyChangeSupport和PropertyChangeListener监听对象。 如果updatedStatus更改,那么我将更新表。MyString类具有私有字符串“ Value”。我想听属性文件。因此,应使updat