First Article

作者在 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正常
*/
默认分类 | 阅读 449 次
文章评论,共0条
游客请输入验证码
浏览2447次
文章分类
最新评论