类学习七

红皮书(P122-P132)

            ——————————终于进入了第四章   2016.3.24

运算符的重载

一、为什么要进行运算符的重载?

为了实现多种定义方式的公用符号但是也不至于发生错误。
例子:“+”重载,计算复数加

#include  <iostream>
using namespace std;
class Complex
{
public:
    Complex( ){ real = 0; imge = 0; }
    Complex(double , double  );
    Complex Complex_add(Complex &c);//注意:返回值类型是Complex类型的。
    void display();

private: 
    double real;
    double imge;
};
Complex::Complex(double r, double i)
{
    real = r;
    imge = i;
}
Complex Complex :: Complex_add(Complex & cc)
{
    Complex c;
    c.real = real + cc.real;        
    //相当于c.real = this->real + c1.real;
    //这个this指针指向的当前调用这个成员函数的对象,
    //对于下面的实例来说是c1
    c.imge = imge + cc.imge;
    return c;
}
void Complex::display()
{
    cout << real << "+" << imge << "i" << endl;
}
int main()
{
    Complex c1(2, 5);
    Complex c2(2.5, 6.5);
    Complex c3;
    c3=c1.Complex_add(c2);
    c3.display();

    system("pause");
    return 0;
}

这个方法是单纯地用了加号的重载来实现的。不像我们之前看到的那样,直接写加号就支持运算。
如果我们想方便的计算,利用通用的形式即:
c3=c1+c2;
怎么实现?

答:运算符的重载!

故思议就是重载运算符的。本质是:函数的重载。
一般格式:
函数类型 operator 运算符名称 (形参表)
{对运算符的重载处理}
例,对加法的重载:
Complex operator + (Complex & c1,Complex &c2);

对上面的代码进行改变:

#include  <iostream>
using namespace std;
class Complex
{
public:
    Complex(){ real = 0; imge = 0; }
    Complex(double, double);
    //*******************运算符的重载声明************************************
    Complex operator +(Complex & ); //运算符的重载
    //*************************************************************************
    //这样做只是为了很直观,重载了+,这样可以直接运用+而不用用自定义的函数
    void display();

private:
    double real;
    double imge;
};
Complex::Complex(double r, double i)
{
    real = r;
    imge = i;
}
//————————————————不同之处————————————————————————
Complex Complex::operator+(Complex& cc)
{
    Complex c;
    c.real = real + cc.real;        //相当于c.real = this->real + c1.real;
    //这个this指针指向的当前调用这个成员函数的对象,对于下面的实例来说是c1
    //(所以它其实是两个参数,一个是隐藏的参数tihs指针指着的是第一个参数,括号里面引用的是第二个参数)
    c.imge = imge + cc.imge;
    return c;
}
//———————————————————————————————————————————————

void Complex::display()
{
    cout << real << "+" << imge << "i" << endl;
}
int main()
{
    Complex c1(2, 5);
    Complex c2(2.5, 6.5);
    Complex c3;
    c3 = c1+c2;    //完整的是c3=c1.operator(c2);
    c3.display();

    system("pause");
    return 0;
}

运算符重载是为了方便。这样用户就不用考虑它怎么实现的,而只要放心的用就行了。

重载规则:

1、不允许定义新的运算符:运算符额重载是重载,所以不允许定义新的运算符,定义了就不叫重载
2、不能重载的运算符: . * :: sizeof ?:
3、重载不能改变运算符所支持的运算对象的个数:一目只能重载成一目,双目只能重载成双目。
4、重载不改变运算符的优先级
5、重载不改变运算符的结合性。
6、重载运算符不能有默认的参数:有了固定的参数则就不叫重载了,只是自己新定义的函数而已,失去了重载的意义。
7、重载的函数必须和用户定义的类对象一起使用,其参数至少是一个类对象。例:
int operator +(int a,int b)
{ return (a-b); }
这样是错的。
Complex operator + (int a ,Complex b)
{ return Complex ( a+c.real , c.imag ) }
这样是允许的。
8、类对象的运算符一般必须重载,=和&不必重载

运算符重载作为类成员函数和友元函数

1、上面的第二个程序是作为类的成员函数的。
2、重载声明为外部函数,但是将其定义成友元函数实现操作:
重载函数作为友元函数实现功能:(部分代码)

#include  <iostream>
using namespace std;
class Complex
{
public:
    Complex(){ real = 0; imge = 0; }
    Complex(double, double);
    //*******************运算符重载成友元函数************************************
    friend Complex operator +(Complex & c1, Complex & c2);  //运算符的重载
    //*************************************************************************
    void display();

private:
    double real;
    double imge;
};
//————————————————不同之处————————————————————————
Complex operator+(Complex & c1, Complex & c2)
{
    Complex c;
    c.real = c1.real + c2.real;//这时候两个变量必须显示的指出来,因为友元函数没有this指针
    c.imge = c1.imge + c2.imge;
    return c;
}

代码二:说明的是重载类型可以不一样:

#include  <iostream>
using namespace std;
class Complex
{
public:
    Complex(){ real = 0; imge = 0; }
    Complex(double, double);
    //*******************运算符重载成友元函数************************************
    friend Complex operator +(Complex & c1, Complex & c2);  //运算符的重载
    friend Complex operator+(int c1, Complex & c2);
    //*************************************************************************
    void display();

private:
    double real;
    double imge;
};
//————————————————不同之处————————————————————————
Complex::Complex(double r, double i)
{
    real = r;
    imge = i;
}
//————————————————一个操作对象是int 另一个是类对象—————————————————————
Complex operator+(int c1, Complex & c2)//必须两个参数
{
    //但是声明以及运用的时候的顺序不能变如果是第一个参数是int则第一个操作数必须是int类型。
    return Complex(c1 + c2.real,  c2.imge);
}
//———————————————————————————————————————————————
void Complex::display()
{
    cout << real << "+" << imge << "i" << endl;
}
int main()
{
    int c1=2;
    Complex c2(2.5, 6.5);
    Complex c3;
    c3 = c1 + c2;//第一个参数是int类型
    c3.display();

    system("pause");
    return 0;
}

一般将双目声明成友元函数,其余的声明成类的成员函数。

后记:今天写了很多了,明天继续介绍,还有两三次就结束这一章了,好几天没自己动手写代码了,今天写下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值