【问题标题】:Casting base class pointer to pointer of class member将基类指针转换为类成员的指针
【发布时间】:2014-10-16 12:53:39
【问题描述】:

问题:

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

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 时返回vmember 的地址。 (或者一般从*WrappedPrimitive&lt;PRIM_TYPE&gt;*PRIM_TYPE

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

背景:

我知道这可能不是一个好主意,但我喜欢它的原因是因为我们将代码移植到了 Linux,其中 myfloat 实际上是一个浮点数,而不是一些包装的值。现在,我们需要用

来区分这些地方
#ifdef _WIN32
manipulateFloat(&myfloat.v)
#else
manipulateFloat(&myfloat)
#endif

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

我的尝试

可以重载operator&函数,

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

但根据这篇文章Overloading unary operator &,这不是最好的主意,因为使用 & 将始终返回 PRIM_TYPE*

【问题讨论】:

  • operator&amp;重载有什么问题?
  • 如果您的函数通过引用获取浮点数,您可以添加operator TYPE&amp;() 如果不是,您必须先将浮点数(值或引用)存储在局部变量中。
  • @KerrekSB 您是否建议为每个具有转换运算符的类重载 operator&amp;
  • 不幸的是,我无法更改函数以获取引用而不是指针。如果是局部变量,我当然必须在之后将其写回原始变量,因为它会被操纵。
  • @NeilKirk:不,我建议对所有超载operator&amp; 的人进行射击。但这不是问题......

标签: c++


【解决方案1】:

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

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);
}

Demo

【讨论】:

    猜你喜欢
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-23
    • 1970-01-01
    • 2018-03-24
    • 2015-08-12
    相关资源
    最近更新 更多