入门1
2种实现方式
1,成员函数
class ST{
?? operator! (){}
};
' 有2种使用方式 '
!obj; 或 obj.operator!();
2,全局函数
?? operator! (ST){}
' 有2种使用方式 '
!obj; 或 operator!( obj );
当然,不可以2种方式都写。 会报ambiguous错误。
即,你的 !obj 这句话
他先变成: operator!( obj ); 看有没有这个全局函数。
如果没有,再变成: obj.operator!(); 看有没有这个成员函数。
Implicit
不要忘记,“某些常用的操作符” 是会有 “默认实现的”
即,即便你的类是空的, “某些”操作符 依然可以使用。
因为,编译器有default的实现版本。
比如, 对于“赋值运算符=” 就自动有这个函数
class ST{ }
( ST() ).operator=( ST() ); 是可行的
' 说明,这个类里,确实有 operator= 这个函数 '
但对于,比如!这个运算符,就没有自动的实现
单目运算符
前置后置运算符
入门
' 前后置运算符,是很“特殊的",不用直接用 通常的规则去看待他!! '
1, 成员函数
class ST{
?? operator++(){ 1 }
?? operator++(int){ 2 }
};
首先,我们先不提运算符,先单单看这2个函数
obj.operator++(); 肯定对应为1
obj.operator++(123); 肯定对应为2
c语言特别规定:
operator++()这种写法,就对应为: 前置
operator++(int)这种写法,就对应为: 后置
++ obj; 等于 obj.operator++();
obj ++; 等于 obj.operator++(123);
' 非常重要的是: 不要以朴素运算符重载规则 去看待它!! '
' 即,你obj ++ 123; 写法是错的!!! 虽然看似是可以的 '
2, 全局函数
?? operator++( ST ){ 1 }
?? operator++( ST, int ){ 2 }
源码
首先, ++obj 和 obj++,本质上 对obj的影响 是相同的!!!
++obj 或 obj++, ??;
对于??, 即逗号,过后的obj,前置和后置的效果 是完全相同的!!!
比如,++对obj的影响是: 让obj.A += 1;
有一点不同是:
++ ++ ++ obj; ' obj += 3 '
obj ++ ++ ++; ' obj += 1 '
obj.A = 123;
DE( ++ obj ), DE( obj ); ' 124, 124 '
DE( (obj ++) ), DE( obj ); ' 123, 124 '
前置++obj, 权限非常高,遇到前置 就要”立即执行“,因此他比较好写
ST& operator++(){
this->A += 1;
return *this; ' 即返回的是个引用,即当前对象本身 '
}
后置obj++, 这个比较复杂
1, 你这个obj,确实需要进行obj.A += 1这个操作
但不是此时此刻,' 但,这个操作 确实是要进行的!! '
2, 我们很容易会想到: 遇到(obj ++)
就, (先: 返回obj这个本身) (再: 执行++操作)
但是,这个想法 就不是“单线程”能实现的了的!!!
因为, (obj ++)的本质 就是: (obj.operator++(123))
即,本质就是 调用了一个函数而已。
' 什么叫做 调用了一个函数??? '
即,在这个函数里 就要“把所有与 后置++相关的事情” 都做完!!!
' 你没有办法说: 这函数,先return obj; 再等到某个时刻,再obj.A += 1 '
这不是单线程能实现的....
即 需求是: 遇到(obj ++)
1, 需要返回一个 与obj值 相等的 一个值
2, ”此时此刻“(即在这个函数里) 就要执行 obj.A += 1的操作
所以,后置++的操作 很简单:
ST operator++(int){
ST tmp = *this;
++ (*this);
return tmp; ' 返回的不是引用本身,而是
}