发现问题:
1.重载自增自减运算符:为什么重载自增(减)运算符并分情况讨论时,前置单目运算符的函数返回值必须为引用?
首先这是个伪命题。。只是课本和现在的教程上大部分都这么写了。引用作为返回值相比类好处更能减少程序开销。前几章我们学过调用构造函数(析构)的第三种情况,那就是作为函数返回值的时候,返回值会自动创建一个临时的副本并调用构造、析构函数。而如果我们用引用作为返回值的话,就省去了这些过程。
以复数运算为例,如果用传统办法:
#include
using namespace std;
class complex{
private:
double r,i;
public:
complex(double a,double b):r(a),i(b){}
void Show(){
cout< complex operator ++(int k); complex operator ++(); }; complex complex::operator ++(int k){ complex t(r,i); r++; i++; return t; } complex complex::operator ++(){ r++; i++; return complex(r,i); } int main(int argc,char** argv) { complex a(1.0,3.0); a++; ++a; a.Show(); ///// complex b=a++; b.Show(); complex c=++a; c.Show(); return 0; } 对比我们把complex的成员函数及其声明改成下面的情况: complex &complex::operator ++(){ r++; i++; return (*this); } 依旧可以获得一样的结果。只是前一个前置自增就不好修改了,因为返回引用时,返回的对象永远是自己,而this指向的值都已经改变了,所以无法做到返回引用。 3 5 3 5 5 7 无参表和int参数表作为区分的重载,没有太多本质原因,就是为了单纯的区分前置与后置。 2.重载输入输出运算符:cout与ostream(cin与istream)为什么要这么写?各自的本质是什么? 以前者为例子,ostream是一个类名,而cout是ostream的对象,它们都在iostream中获得定义,并通过调用实例化的对象cout来控制输出。因此如果要重载<<的话,就需要对cout上属的ostream类重载。 #include using namespace std; /* run this program using the console pauser or add your own getch,system("pause") or input loop */ class complex{ private: double r,i; public: complex(double a=1.0,double b=2.0):r(a),i(b){} friend ostream &operator <<(ostream &os,const complex &c); }; ostream &operator <<(ostream &os,const complex &c){ os<< c.r << "+"< return os; } int main(int argc,char** argv) { complex a;