gpt4 book ai didi

C++从成员指针转换回持有类指针

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:18:44 26 4
gpt4 key购买 nike

我有以下类(class):

class SSVec
{
public:
float values[8];
}

我有一个对象 SSVec obj,我将 float* 指针 obj.values 传递给另一个函数。在代码的其他地方,我得到了这个 float* 指针,然后将它转换回 SSVec* 指针。

这在 C++ 标准定义的行为方式中可能吗?大多数情况下,这将适用于静态转换,但我猜这实际上是未定义的行为。

原因是 float* 指针传入和传出 DLL,而 DLL 对 SSVec 一无所知。我保证传递的指针始终指向 SSVec::value[8] 对象成员。

该类可能更复杂,但它不派生自任何东西,没有虚函数,并且只包含 POD 类型。 values 是第一个成员

问题可以重新表述:是否通过 static_cast 保证类地址和第一个成员地址相同?

最佳答案

如果 SSVec 是 POD 类型,则定义行为。在为你的类型实现一个特殊的转换函数时,你可以静态断言:

SSVec* SSVec_cast(float* ptr) {
// Break if someone changes SSVec to be no POD anymore:
static_assert(std::is_pod<SSVec>::value, "SSVec is no longer a POD!");

// Break if someone changes SSVec to contain more than the array:
// [ NOTE: This is optional. Behavior is still defined if the structure
// changes(*), but then only if the pointer really points into an SSVec.
// With these assertions included, you can even cast from a different
// float array of size 8, even if it hasn't been declared as a SSVec. ]
static_assert(sizeof(SSVec) == 8 * sizeof(float), "SSVec has wrong size!");
static_assert(sizeof(SSVec::values) == sizeof(SSVec), "SSVec has wrong structure!");
static_assert(offsetof(SSVec, values) == 0, "SSVec has wrong structure!");

// Now it is safe to reinterpret cast the pointer:
// [ (*) NOTE: If above assertions are removed, please change (ptr)
// to (reinterpret_cast<char*>(ptr) - offsetof(SSVec, values)). ]
return reinterpret_cast<SSVec*>(ptr);
}

同样可以通过重载对 const 指针完成;当然,您随后可以将这些断言移动到一些通用函数或全局范围内(最好)。


PS:请查看std::array .它完全符合您的要求:

typedef std::array<float,8> SSVec;

关于C++从成员指针转换回持有类指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27520620/

26 4 0