- 注册时间
- 2008-12-31
- 最后登录
- 1970-1-1
- 威望
- 星
- 金币
- 枚
- 贡献
- 分
- 经验
- 点
- 鲜花
- 朵
- 魅力
- 点
- 上传
- 次
- 下载
- 次
- 积分
- 6090
- 在线时间
- 小时
|

楼主 |
发表于 2009-6-1 15:36:42
|
显示全部楼层
本帖最后由 winxos 于 2009-6-1 15:49 编辑
其实在C++中,操作符同函数可以看成没有区别,其唯一的区别是对操作符添加了一些特殊的使用方法.
而对于所有的类成员函数(包括类成员操作符),我们可以把this指针(指向类本身)总是看成函数的第一个参数.
那么在这个意 ...
mathe 发表于 2009-5-31 17:35 
我写了下面的测试代码,麻烦mathe看看对不对?
- /*
- c++ 语言运算符重载以及临时变量问题的测试程序。
- winxos 2009-06-01
- */
- #include <iostream>
- #include <string>
- using namespace std;
- #define NUM_LEN 10
- static int idnum=0; //标记对象
- class Test
- {
- public:
- Test():name("null"),age(0),id(++idnum) //空参数构造
- {
- num=new int[NUM_LEN];
- for(int i=0;i<NUM_LEN;i++)
- num[i]=0;
- }
- Test(string n):name(n),age(0),id(++idnum) //1个参数(姓名)的构造
- {
- num=new int[NUM_LEN];
- for(int i=0;i<NUM_LEN;i++)
- num[i]=i;
- }
- Test(string n,int a):name(n),age(a),id(++idnum) //2个参数(姓名,年龄)的构造
- {
- num=new int[NUM_LEN];
- for(int i=0;i<NUM_LEN;i++)
- num[i]=i*2;
- }
- Test(Test &b) //拷贝构造
- {
- num=new int[NUM_LEN]; //深拷贝
- copy(b.num,b.num+NUM_LEN,num);
- age = b.age ;
- name =b.name ;
- id=(++idnum);
- }
- ~Test() //析构
- {
- cout<<"ID: "<<this->id <<" destoryed!"<<endl;
- delete []num;
- }
- /*
- mathe所说的:前缀重载使用X& operator++(X& x);
- 我测试之后发现是否用引用似乎对结果没有影响,不知道具体有什么差别?
- */
- Test operator ++ (int) //后缀重载,注意括号内一定是一个int而且不能在变量
- {
- Test ret(*this); //后缀返回值不变
- this->age++;
- return ret; //编译时为何这里不会出现返回临时变量的警告呢?是否由于拷贝构造函数的存在使之等价于Test(ret)?
- }
- Test operator ++ () //前缀
- {
- this->age++;
- return (*this);
- }
- /*
- 这里非常重要,如果未重载赋值号的话,将造成返回临时变量,会导致析构出错。尾部附有重载与未重载时的运行结果差别。
- */
- bool operator = (const Test &b) //
- {
- copy(b.num,b.num+NUM_LEN,num);
- age = b.age;
- name =b.name;
- return true;
- }
- /*
- 如何实现!的后缀运算?
- 如果加入参数将 error C2808: 一元“operator !”的形参太多
- */
- int operator ! () //前缀符号
- {
- return (this->age)*(this->age);
- }
- friend ostream& operator << (ostream &out,Test &t) //重载输出流
- {
- out<<"ID: "<<t.id<<"'s name is: "<<t.name<<"\tMy age is: "<<t.age<<" Value:";
- for (int i=0;i<5;i++)
- out<<t.num[i]<<" ";
- out<<endl;
- return out;
- }
- private:
- string name;
- int age;
- int *num;
- int id;
- };
- int main()
- {
- Test a,b("winxos"),c("emath",1);
- cout<<a<<b<<c<<endl;
- a=b++;
- cout<<b<<a<<endl;
- a=++b;
- cout<<b<<a<<endl;
- /*
- 我还想实现的重载:
- 比如如何实现 int i=b;
- 其中b为Test类,这个操作实现将b.age赋值给i,请问如何实现?
- */
- int i;
- i=!b; //前缀运算没问题,如何重载能够使用 i=b!
- cout<<i<<endl;
- /*
- 还有一个问题,如何重载 ** 符号?(两个乘法连在一起)
- 直接照例会出现 error C2143: 语法错误 : 缺少“;”(在“*”的前面)
- */
- return 0;
- }
- /*
- 测试程序:
- Test a,b("winxos"),c("emath",1);
- cout<<a<<b<<c<<endl;
- a=b++;
- cout<<b<<a<<endl;
- a=++b;
- cout<<b<<a<<endl;
- 之前未重载赋值号时出现奇怪错误,debug模式下运行出错,release模式有结果,但是明显有问题,运行结果如下:
- ID: 1's name is: null My age is: 0 Value:0 0 0 0 0
- ID: 2's name is: winxos My age is: 0 Value:0 1 2 3 4
- ID: 3's name is: emath My age is: 1 Value:0 2 4 6 8
- ID: 4 destoryed!
- ID: 5 destoryed!
- ID: 2's name is: winxos My age is: 1 Value:0 1 2 3 4
- ID: 5's name is: winxos My age is: 0 Value:-572662307 -572662307 -572662307 -57
- 2662307 -572662307
- ID: 6 destoryed!
- ID: 2's name is: winxos My age is: 2 Value:0 1 2 3 4
- ID: 6's name is: winxos My age is: 2 Value:-572662307 -572662307 -572662307 -57
- 2662307 -572662307
- ID: 3 destoryed!
- ID: 2 destoryed!
- ID: 6 destoryed!
- 请按任意键继续. . .
- 我们可以发现执行 a=b++;后,输出a,发现a的id变成了5,说明a已经指向临时变量了,所以导致了析构出错。
- 重载之后结果如下:
- ID: 1's name is: null My age is: 0 Value:0 0 0 0 0
- ID: 2's name is: winxos My age is: 0 Value:0 1 2 3 4
- ID: 3's name is: emath My age is: 1 Value:0 2 4 6 8
- ID: 4 destoryed!
- ID: 5 destoryed!
- ID: 2's name is: winxos My age is: 1 Value:0 1 2 3 4
- ID: 1's name is: winxos My age is: 0 Value:0 1 2 3 4
- ID: 6 destoryed!
- ID: 2's name is: winxos My age is: 2 Value:0 1 2 3 4
- ID: 1's name is: winxos My age is: 2 Value:0 1 2 3 4
- ID: 3 destoryed!
- ID: 2 destoryed!
- ID: 1 destoryed!
- 请按任意键继续. . .
- 我们可以发现a的id正常
- */
|
|