作者在 2010-06-23 19:41:57 发布以下内容
/*
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;
}
int operator ! () //前缀重载,单目运算符可能无法实现后缀重载
{
return (this->age)*(this->age);
}
friend ostream& operator << (ostream &out,Test &t);//友元函数声明,函数体最好是要放到类的外部。
private:
string name;
int age;
int *num;
int id;
};
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;
}
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正常
*/
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;
}
int operator ! () //前缀重载,单目运算符可能无法实现后缀重载
{
return (this->age)*(this->age);
}
friend ostream& operator << (ostream &out,Test &t);//友元函数声明,函数体最好是要放到类的外部。
private:
string name;
int age;
int *num;
int id;
};
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;
}
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正常
*/