将基类指针强制转换为类成员的指针

Casting base class pointer to pointer of class member

本文关键字:指针 成员 基类 转换      更新时间:2023-10-16

问题:

我们确实有一个基于模板的类,它提供了一些关于基元类型的功能(例如序列化、反序列化…)

template <typename PRIM_TYPE> class WrappedPrimitive
{
public:
    PRIM_TYPE v;
    //lots of other methods, including serialization and deserialization
    PRIM_TYPE & operator= (const PRIM_TYPE & value) { v = value; return v; }
    operator PRIM_TYPE() const          { return v; }
};
typedef WrappedPrimitive<float>        WrappedPrimitiveFloat;

假设我有一个功能

void maninpulateFloat(float *f) {*f = 5.0f;}

有没有办法添加一些类函数,使其在从*WrappedPrimitiveFloat转换为*float时返回v成员的地址。(或者一般从*WrappedPrimitive<PRIM_TYPE>*PRIM_TYPE

WrappedPrimitiveFloat myfloat;
manipulateFloat(&myfloat.v) // This works
manipulateFloat(&myfloat)   // Is there any way to make this work?

背景:

我知道这可能不是一个好主意,但我之所以喜欢它,是因为我们将代码移植到了Linux,在那里myfloat实际上是一个float,而不是一些封装的值。现在,我们需要用来区分这些地方

#ifdef _WIN32
manipulateFloat(&myfloat.v)
#else
manipulateFloat(&myfloat)
#endif

这也真的很丑陋。或者,我会很高兴有一行代码可以在Windows/Linux上运行。

我尝试过的

有可能使操作者&功能,

PRIM_TYPE * operator& () {return &v;}

但是根据这篇文章重载一元运算符&这不是最好的主意,因为使用&将始终返回CCD_ 6。

您可以实现模板get_address()函数,并在需要的任何地方使用它,而不是一元&:

template <typename PRIM_TYPE> class WrappedPrimitive
{
public:
    operator PRIM_TYPE() const { return v; }
    // these conversions are necessary to implement
    operator PRIM_TYPE&() { return v; }
    operator const PRIM_TYPE&() const { return v; } 
};

template <typename PRIM_TYPE>
PRIM_TYPE* get_address(PRIM_TYPE& v) {
    return &v;
}
template <typename PRIM_TYPE>
PRIM_TYPE* get_address(WrappedPrimitive<PRIM_TYPE>& wp) {
    return &static_cast<PRIM_TYPE&>(wp);
}
template <typename PRIM_TYPE>
const PRIM_TYPE* get_address(const WrappedPrimitive<PRIM_TYPE>& wp) {
    return &static_cast<const PRIM_TYPE&>(wp);
}

演示