gal*_*tte 4 c++ casting class member
我有以下课程:
class SSVec
{
public:
float values[8];
}
Run Code Online (Sandbox Code Playgroud)
我有一个对象SSVec obj,我将float*指针传递obj.values给另一个函数.在代码的其他地方,我得到这个float*指针,然后用魔杖将它强制转换为SSVec*指针.
这是否可能以C++标准定义的行为方式?大部分时间这都适用于静态演员,但我的猜测是它实际上是未定义的行为.
这样做的原因是float*指针传入和传出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);
}
Run Code Online (Sandbox Code Playgroud)
通过重载可以使用const指针完成相同的操作; 当然,您可以将这些断言移动到某个共同功能或全局范围(最好).
PS:请看看std::array.它完全符合您的要求:
typedef std::array<float,8> SSVec;
Run Code Online (Sandbox Code Playgroud)