C++垫片类(2)

来源:互联网 发布:linux acpi驱动 编辑:程序博客网 时间:2024/05/17 04:00

这次我们要用垫片类实现一个C++不直接支持的语法:根据返回值重载函数。

首先有以下两个函数

int GetValueInt(const void* ptr);        { return *(const int*)ptr; }  float GetValueFloat(const void* ptr);    { return *(const float*)ptr; } 

功能是按照指定类型从某块内存中读取数据。
我们的目标是实现

int i = GetValue(ptr);    //调用GetValueInt  float f = GetValue(ptr);  //调用GetValueFloat

C++在重载函数时要求参数必须不同,因此上述目标是无法直接实现的。只能通过别的方法间接实现。

方式一,模板
通过模板的特化功能来指定不同返回值时的函数调用,不过在调用时仍然需要显式指定返回值类型。

template<typename type_t>type_t GetValue_V1(const void* ptr){    return type_t();}template<> int GetValue_V1<int>(const void* ptr){    return GetValueInt(ptr);}template<> float GetValue_V1<float>(const void* ptr){    return GetValueFloat(ptr);}int i = GetValue_V1<int>(ptr);     //调用GetValueIntfloat f = GetValue_V1<float>(ptr); //调用GetValueFloat


方式二, 参数提示
将返回值类型作为额外参数传递给函数,该参数虽然在函数实现中没有用,但是在函数调用时能够区别出不同函数。

int GetValue_V2(const void* ptr, int){    return GetValueInt(ptr);}float GetValue_V2(const void* ptr,float){    return GetValueFloat(ptr);}int i = GetValue_V2(ptr, 1);      //调用GetValueIntfloat f = GetValue_V2(ptr, 1.0f); //调用GetValueFloat


方式三,垫片类
在调用时不直接调用内存读取函数,而是把参数构造成一个垫片类并返回。然后垫片类会根据最终的数据类型调用不同的运算符重载函数,此时才进行内存读取。

class cGetValueShim{public:    cGetValueShim(const void* ptr) : m_ptr(ptr) {}    operator int() const  { return GetValueInt(m_ptr); }    operator float() const { return GetValueFloat(m_ptr); }private:    const void*  m_ptr;};cGetValueShim GetValue_V3(const void* ptr){    return cGetValueShim(ptr);}int i = GetValue_V3(ptr);    //调用GetValueInt  float f = GetValue_V3(ptr);  //调用GetValueFloat  
原创粉丝点击