如何用C++ union 来 实现一个 C# object

C#的 object 相信用过的人都能体会出它的优点, 可以  实现 任意类型的boxed,unboxed , 如下  int n = 10;   object o = n;    int m = (int) o;   在类型的传递中可以起到一个自适配的容器, 这种写法 在接口的统一 上  能起到很好的作用 , 比如你不知道如何传递一个未知类型的参数时 , 你可以在接口处定义 object 参数让 真正接口的实现者自己去抉择。  说到这 可能有不少惯用 C 的人会说 这不就是一个变向的 void* 么, 恩这话说对了一半,但 void * 的不安全性在于 当使用者 用错类型的时候可能会出现访问越界  。 但 object因为本身的 沙盒 特性避免了一部分外部对它内部空间的越界操作。   在 C++ 的世界里也有 一个 void* 的替代品 ,那就是 union 。 union 理论上可以实现所有类型的容器 ,虽然得面对个问题 : union 也需要你使用者知道传递的类型而且 还必须 保证知道 union 内部的构造, 比如  union UData { unsinged int nU32; }  当用到UData ud 给 外部赋值的时候 就得用  unsinged int  n = ud.nU32; 这种显式的方式把 nU32这种内部结构暴露给使用者。  有什么方法能保证 外部使用的时候不关心这点呢 ,其实外部 变量 n 已经提供给编译器 自己的变量 类型 unsinged int 了, 如果编译器自己 知道 该从 union上取到 nU32这种东西就好了  。。。。 答案是否定的, 编译器怎么会知道你 union里面还包含了个 nU32 , 当你想写出 n = ud ; 这种 自然的 等式 时 ,编辑器该上哪去找 nU32?   等等 貌似 有这种问题的解决 方式 ,就是  operator 符号 ,但这种符号常常在 class , struct 里出现 ,但 union 能不能支持 ? 带这种疑问试验了 如下的写法 :

union UData
{
     unsinged int nU32;
     operator unsigned int() { return nU32; }
};

unsigned int _n;  
UData _d; 
_d.nU32 = 1; 
_n = _d;

luck ,编辑器认识,并且正确的把 1 付给了 n ;  问题看上去解决了, 但是 _d.nU32 似乎还是让外部看见了。 恩, 万能的 operator 貌似也能解决这个问题

union UData
{
     unsinged int nU32;
     void operator (const unsigned int& right) { nU32 = right;};
     operator unsigned int() { return nU32; }
};

unsigned int _n;  
UData _d; 
_d = 1; 
_n = _d;


好了,ok  。但似乎还是有不舒服的地方, 一个 union 定义写这么大块,不太容易看于是 最终懒汉方案产生

#define _UNION_CONVER(type,var)       type  var; \
                                      void operator=( const type& _right) { var = _right;};\
                                      operator type{ return var;} 

union UData
{
     _UNION_CONVER(unsigned int , nU32);
     _UNION_CONVER( int , n32);
     _UNION_CONVER( bool , bBool);
     _UNION_CONVER( float , fFloat);
};

UData _d;
_d = 1;
unsinged int _n = _d;
_d = -1;
int _m = _d;
_d = false;
bool _b = _d;
_d = 0.02f;
float _f = _d;


值得注意的是要防止typedef过的类型在注册的时候重定义,比如 typedef 了一个 int 的 PID  ,那么 PID nID在 UData 中就不能使用 _UNION_CONVER 这个宏了,但是可以如下的方式定义, 同样不影响 nID的赋值和取值

union UData
{
     _UNION_CONVER(unsigned int , nU32);
     _UNION_CONVER( int , n32);
     _UNION_CONVER( bool , bBool);
     _UNION_CONVER( float , fFloat);
     PID nID:
};
好吧得承认面对新类型时还得在添加一句 _UNION_CONVER 这种做法还是没有C# object 用着爽,但毕竟那是  keyword,  编译器支持的, 如果C++ 编译器在编译新的类型时也能如 template一样自动填写一个变量类型就完美了。  顺带一提 g++编辑器也能支持 这种 union 里面的 嵌operator 写法

 
 
 

                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值