网站建设图片尺寸,科技网站建设总结,常见的网络营销推广方法,汕头推广公司漫谈C重载运算符 1.前置运算符和后置运算符#xff0c;左值和右值 其实很久以来一直都没有怎么搞清楚左值和右值的区别#xff0c;只知道左值可以放在等号的左边#xff0c;也可以放在等号的右边#xff0c;但是右值却只能放在等号的右边#xff0c;然后形成一个大概直观…漫谈C重载运算符 1.前置运算符和后置运算符左值和右值 其实很久以来一直都没有怎么搞清楚左值和右值的区别只知道左值可以放在等号的左边也可以放在等号的右边但是右值却只能放在等号的右边然后形成一个大概直观的印象知道怎么样做才不出错而已。不过今天看看C却发现有了点新的体会。 对于表达式a--5;这样一个表达式明显是错误的究其原因是因为执行等号左边的自减表达式之后显示取得a的值然后才是进行自减操作所以最终的结果是一个右值而且就是a的值变化前的于是对于赋值语句 b a--,自然不会弄错了。 而对于--a5;这样一个表达式则明显就不同了。首先执行的是自减操作然后返回的是a的值变化后的于是自然就可以将返回的a值再次赋值了。也就是说前置的运算符是左值表达式而后置的则是右值表达式。于是我想到了很久前的一个想法a 5;当然行家肯定一看就知道是错误的可是错误的地方需要改正啊。于是我想到了几种方法就是通过加括号的方法来实现。 1(a) 5; 其实通过错误信息就可以看到原因了error: non-lvalue in increment 明显说明在自增运算符中的那个表达式不是左值所以不能自增运算了。哦对啊a是右值于是的话再次进行的操作就是错误的因为操作需要的表达式是左值表达式。于是此处的方法行不通。 2(a) 5;此处也不行错误信息就是: error: non-lvalue in assignment,通过前面的表述就知道了其实a是左值表达式那么后面的那个操作就是一个错误了赋值的时候等号的左边不是左值表达式因为括号外的是一个后置的运算符。于是就得到了错误。 通过上面的这些折腾对于a等等变态的表达式相信也就有更深刻的体会了。 2.重载前置和后置的时候的不同 相信很多人都做过这种操作了对于后置的需要多一个形参int来说明但是从上面的分析还需要注意的是两者的左值和右值的区别重载的目的也不过是为了更加符合用户的习惯于是我们对于前置的自然要返回的是左值表达式而对于后置的需要返回的则是左值表达式。当然具体的来说说吧。 前置如果自定义了一个类A含有一个数据成员x那么要重载它的前置运算符根据习惯首先就是对它的数据成员然后再返回它的引用这样才是左值表达式于是下面的代码 A A::operator(){ x; return *this ; }这样的方法自然很好的表达了前置的作用先运算在返回值。 后置如果同上面的例子要定义后置的话那么需要注意的是它的右值性此时是返回引用还是类类型呢思考了很久一般来说返回的是引用的都是左值表达式而如果此处返回的是引用那么就可能在后面的代码中出现问题。 于是出现了下面的这样的代码 A A::operator(int ) { return A(this-x); } 其实我觉得此句甚好既表达了后置的意思又成功的返回了值。后置的含义也就是先返回之后再进行自增操作于是此处调用的是默认的拷贝构造函数来实现返回一个临时的变量。 3.重载函数的参数问题 以前的时候被这个问题纠结的不行了后来明白了一点今天看看书明白的更多了现在才明白古人那句“书读百遍其义自见”的至理名言了。也更加的明白了读书的重要性。 对于运算符重载我们常用的既可以作为成员函数也可以作为普通函数这点都知道而且此时的参数不同作为成员函数的话因为在类中所以有一个隐藏的this指针于是双目运算符就只要写出来一个就可以而单目运算符就不需要写出来。同样的是一个重载运算符可以有两种表示的方法如A operator(A, int value); //此为普通的函数 A A::operator(int value) ; //此为成员函数 对于上面的这两个典型的例子很容易而直白的理解在调用的时候写下 a 5; 其中a是A类型的变量这样就OK了。但是深入思考下重载的是运算符那么双目的运算那两个参数的顺序是如何区分呢很简单前面的那个操作符就是第一个操作符而后面的那个就是第二个运算符。对于是成员的函数那么就要注意this指针的作用所以也就说明指代的对象的重要性了。为何我这么简单的东西还要思考呢因为被我们书上的一个变态程序搞懵了如下 #include iostream
using namespace std;
struct A{
int a;
A(int x){a x;}
};
class B{
A x;
public:
A *operator-();
B(int v):x(v){}
};
A *B::operator-(){
return x;
}
int main()
{
B b(5);
int i b-a;
b-a i5;
i (*b.operator-()).a;
}
各位可以看看其实道理很简单不过是重载了-而且重载的比较变态让人有点琢磨不透而已。对于箭头运算符一般的左边为指针不过这里重载的话左边为一个类对象注意看声明时在B中的所以左边的那个就是B类型的变量也就是b而这个是单目运算符于是重载之后返回的指针照理说应该是b- –a,因为左边做了操作之后返回的是指针然后再访问a不过应该是这里的编译器处理或者规定所以就只剩下了一个-从此处我看出来了重载的参数顺序以及参数的个数。以前总是手动的加上个参数或者少一个现在将this算入其中然后看是否为成员就可以得到确定的数目然后就可以知道具体的调用顺序了。