c++ - 调用从不兼容类型转换而来的零数据结构的成员函数 - 未定义?

标签 c++ struct reinterpret-cast

在不可修改的 header 中声明了前向 C 结构。我想“虚拟地”向它添加便利的成员函数。显然,我的第一选择是扩展结构并将方法添加到派生类。不行,因为结构本身在 header 中声明为“转发”,所以我收到错误“错误:不完整类型的无效使用...”。如果我尝试使用旧结构的单个元素定义新结构,我会收到类似的错误。这很糟糕。

但是,我在想我可以用 reinterpret_cast 做一些 hacker 来让它工作。它的运行方式是这样的:

//defined in header
struct A forward;
void do_something_with_A(A* a, int arg);

//defined in my wrapper
struct B {
  B* wrap(A* a) {return reinterpret_cast<B*>(a); }
  void do_something(int arg) {do_something_with_A(reinterpret_cast<A*>(this),arg); }
}

如果我添加从类型 B 到类型 A 的隐式转换,我认为这可以解决几乎,就好像 B 是 A 的零数据继承者一样。然而,这显然带来了问题:这在 C++ 中是未定义的吗?通常我会认为访问非法转换的结构的元素是未定义的;这就说得通了。但是,我认为将 reinterpret_casting 从一种类型转换为另一种类型,传递该指针,然后再次转换回来,中间不做任何非法的事情就可以了。我还认为编译器实现非虚拟结构成员的方式是创建一个函数

B::do_something(B* b, int arg)

并使用 B 的适当参数调用它。然后这将简化为之前的情况,根据我可疑的逻辑,这是可以的。所以我认为在实际上是 reinterpret_cast A 的结构上调用 .do_something 是可以的。

然而,这并没有说明 C++ 标准在这个问题上的实际说法。有什么帮助吗?此外,如果有人知道这在实际工作中的效果如何(即“每个编译器都接受这个”,或“这只适用于少数编译器”),那也会有所帮助,但稍微不那么有用。

最佳答案

我相信,如果您将 A* 转换为 B*,然后再次将其转换回 A*,那么标准会说您没问题。这些将是 reinterpret_casts 而不是 static_casts。

但是正常的解决方案到底有什么问题呢?

class B
{
private:
  A* ptr;
public:
  B(A* p) : ptr(p) {}
  void do_something(int arg) { do_something_with_A(ptr,arg); }
};

似乎与您的解决方案一样高效,而且不费吹灰之力。

关于c++ - 调用从不兼容类型转换而来的零数据结构的成员函数 - 未定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7170394/

相关文章:

c++ - 在单编写器多阅读器情况下,是否需要为uint64_t锁定?

调用结构数组,是否返回指针数组?

go - 在 struct golang 中为 struct 赋值时出错

c++ - qobject_cast 是如何工作的?

C++ 重新解释_cast

c++ - 删除对象时无法调用 __dealloc__

c++ - 如何从集合中删除共享 ptr 元素?

pointers - 如何创建新结构并将其原始值用作新结构的成员

c++ - 为什么使用reinterpret_cast 将char* 转换为结构似乎可以正常工作?

android - 是否可以在 Flutter 应用程序中使用 C++ 进行网络编程?