博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
对C++的改造#2 属性(2)
阅读量:4841 次
发布时间:2019-06-11

本文共 3622 字,大约阅读时间需要 12 分钟。

这次这篇就讲一下怎么把之前定义的属性变平滑,我之前就说了,把能重载的运算符都重载一遍就行了

单目运算符:

#define OPERATOR1(op) \template
\auto operator op (const Property
& l) -> decltype(op l->get()){ \ return op l.get(); \}OPERATOR1(!);OPERATOR1(~);OPERATOR1(*);//不建议重载取地址运算符,如果你确实需要的话也可以重载//OPERATOR1(&);#undef OPERATOR1

双目运算符:

#define OPERATOR2(op) \template
\auto operator op (const Property
& l, const R& r) -> decltype(l.get() op r) { \ return l.get() op r; \} \template
\auto operator op (const Property
& l, const Property
& r) -> decltype(l.get() op r.get()) { \ return l.get() op r.get(); \} OPERATOR2(+); OPERATOR2(-); OPERATOR2(*); OPERATOR2(/); OPERATOR2(%); OPERATOR2(>>); OPERATOR2(<<); OPERATOR2(|); OPERATOR2(||); OPERATOR2(&); OPERATOR2(&&); OPERATOR2(^); OPERATOR2(>); OPERATOR2(<); OPERATOR2(>=); OPERATOR2(<=); OPERATOR2(==); OPERATOR2(!=);#undef OPERATOR2

复合运算符:

#define OPERATOREX(op) \template
\Property
& operator op##=(Property
&l, const R& r) { \ auto v=l.get();\ v op##= r;\ l.set(v); \ return l; \} \template
\Property
& operator op##=(Property
&l, const Property
& r) { \ auto v=l.get();\ v op##= r.get();\ l.set(v); \ return l; \} OPERATOREX(+); OPERATOREX(-); OPERATOREX(*); OPERATOREX(/); OPERATOREX(%); OPERATOREX(>>); OPERATOREX(<<); OPERATOREX(|); OPERATOREX(&); OPERATOREX(^);#undef OPERATOREX

 自增自减运算符:

  template
auto operator++(Property
& l, int) -> decltype(l.get()++) { auto x = l.get(); auto ret = x++; l.set(x); return ret; } template
auto operator++(Property
& l) -> decltype(++l.get()) { auto x = l.get(); ++x; l.set(x); return x; } template
auto operator--(Property
& l, int) -> decltype(l.get()--) { auto x = l.get(); auto ret = x--; l.set(ret); return ret; } template
auto operator--(Property
& l) -> decltype(--l.get()) { auto x = l.get(); --x; l.set(x); return x; }

重载中括号(写在类里面)

//作左值template 
auto operator[](I i) -> decltype(_value[i])&{ return _value[i];}//作右值template
auto operator[](I i) const -> const decltype(_value[i])& { return _value[i];}

 

 重载箭头(写在类里面)

const T operator->() const{    return get();}T operator->() {    return get();}

 

重载圆括号(写在类里面)

template
auto operator()(Types...args) -> decltype(_value(args...)){ return _value(args...);}template
auto operator()(Types...args) const -> decltype(_value(args...)) { return _value(args...);}

 

好了,现在能重载的运算符就都重载了,剩下还有一些不能重载的运算符,那些也无能为力了,不过除了点号"."其余要么不常用,要么没重载的必要,而点号禁止重载我们也没办法,但是我们可以重载箭头运算符,我们可以在被包装类型不是指针型的时候用箭头进行被包装类型的成员调用,点号进行属性类型的成员调用。而被包装类型时指针时保持原含义。

那么上面的重载箭头需要改改了,运用模板类型的特化:

template
class Property{... const T* operator->() const{ return &get(); } T* operator->() { return &get(); }...}template
class Property<_T*>{... typedef _T* T;... const T operator->() const{ return get(); } T operator->() { return get(); }...}

 

不过这种写法有个缺点,就是如果被包装的类型重载了箭头运算符,那么将无法调用,虽然这种情况较少,但到底怎么重载箭头运算符还是看个人喜好吧。

关于属性的东西就暂时这样了,当然,还没完,还记得C#有个依赖项属性么,还有属性绑定之类的东西,不过那个东西需要处理事件,所以下一章不出意外的话就是类似Event或者Delegate之类的东西的实现。

转载于:https://www.cnblogs.com/zwork/p/3865222.html

你可能感兴趣的文章
软考错题合集之14-11-AM
查看>>
大二暑假周记第三篇
查看>>
poj3286_How many 0's?
查看>>
Kubernetes Service 模板
查看>>
Quartus II& Nios II 出错解决办法
查看>>
[leetcode-110]balanced-binary-tree
查看>>
Oracle 日期查询
查看>>
python diango学习笔记一
查看>>
ActiveMQ
查看>>
linux下实现nginx安装实现端口区分,域名区分
查看>>
CentOS7.2环境下安装Nginx
查看>>
MFC动态创建控件及其消息响应函数
查看>>
团队作业_1_博客1(分工理解)
查看>>
mybatis 一对多和一对一写法注意事项
查看>>
三、使用vscode在docker中debug
查看>>
设计模式之 面向对象的养猪厂的故事,C#演示(一)
查看>>
分页及字母筛选
查看>>
Expressions are not allowed at the top level
查看>>
非程序员的GNU Emacs使用心得......Shell Mode 第13集 把我的 kill-ring 还给我
查看>>
15.C#回顾及匿名类型(八章8.1-8.5)
查看>>