【问题标题】:What is the best way to determine object pointer by pointer to one of it's members?通过指向其中一个成员的指针来确定对象指针的最佳方法是什么?
【发布时间】:2015-06-08 11:09:44
【问题描述】:

如果我有:

struct S
{
    std::size_t szArray;
    int dArray[];
} ;

int main()
{
    extern int (*pArr)[]; //pointer to member 'dArray' of object with type 'S'

    S *pStruct = /*??????????*/; //pointer to the object
}

获取此指针的最佳方法是什么?

【问题讨论】:

  • 您知道数组自然会衰减为指向其第一个元素的指针吗?此外,标准 C++ 不支持结构中的灵活数组,如果结构中有数组,则它必须在编译时具有大小,否则使用 std::vector
  • 我知道,但我想使用指向数组的指针来保存它们指向多个对象而不是一个对象的信息。无论如何 - 我不知道为什么我留下的印象是 C++ 支持灵活数组,但在任何情况下都不会改变这种情况。

标签: c++ pointers structure c++14


【解决方案1】:

没有好办法。

唯一支持的方式是

#include <cstddef> // for offsetof

S *pStruct = reinterpret_cast<S*>
    (reinterpret_cast<char*>(pArr) - offsetof(S, dArray));

请注意,offsetof 仅针对标准布局类型进行了明确定义,并且标准 C++ 不允许将未调整大小的数组作为类成员。除非你有充分的理由使用 C 习语,否则我建议 std::vector&lt;int&gt; 会更安全、更方便。

【讨论】:

  • 我会把static_assert(std::is_standard_layout&lt;S&gt;(), "S must be standard layout for this to work."); 放在那里(a)让正在发生的事情一目了然,并且(b)面向未来。
  • 可以使用大小为 1 的数组来替换空数组。在数组末尾分配“额外空间”的技术可能有效?并且“过度索引”可以保证工作?但我不确定。如果不能保证,它应该是,因为它是一种非常典型的 C 技术,我想不出一个不能使用它的实现(使用 POD 类型)。有趣的是,您可能需要 2 种结构——一种只有大小,另一种具有大小和 1 个元素的数组——以使标准布局保证适合您。
  • @Yakk:是的,如果你有充分的理由,这个成语可以在 C++ 中工作。但正如我所说,您需要一个充分的理由,因为它比等效的 C++ 习惯用法更不安全和方便。
  • 让我困扰的是,如果 'char' 保证为单个字节的大小。
  • @FISOCPP:是的,根据定义。
猜你喜欢
  • 2011-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-25
  • 2012-08-20
  • 2023-01-28
  • 2010-09-18
  • 2014-01-02
相关资源
最近更新 更多