码迷,mamicode.com
首页 > 其他好文 > 详细

类和对象(17)—— 操作符重载

时间:2018-10-19 22:05:36      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:否则   namespace   ons   不同   技术分享   float   相减   语法   运算符重载   

1、操作符重载的基本语法

  所谓重载,就是重新赋予新的含义。函数重载就是对一个已有的函数赋予新的含义,使之实现新功能,因此,一个函数名就可以用来代表不同功能的函数,也就是”一名多用”。

  运算符也可以重载。实际上,我们已经在不知不觉之中使用了运算符重载。例如,大家都已习惯于用加法运算符”+”对整数、单精度数和双精度数进行加法运算,如5+8,5.8+3.67等,其实计算机对整数、单精度数和双精度数的加法操作过程是很不相同的,但由于C++已经对运算符”+”进行了重载,所以就能适用于int,float,doUble类型的运算。

  又如”<<“是C++的位运算中的位移运算符(左移),但在输出操作中又是与流对象cout配合使用的流插入运算符,”>>“也是位移运算符(右移),但在输入操作中又是与流对象cin配合使用的流提取运算符。这就是运算符重载(operator overloading)。C++系统对”<<“和”>>“进行了重载,用户在不同的场合下使用它们时,作用是不同的。对”<<“和”>>“的重载处理是放在头文件stream中的。因此,如果要在程序中用”<<“和”>>”作流插入运算符和流提取运算符,必须在本文件模块中包含头文件stream(当然还应当包括”using namespace std“)。现在要讨论的问题是:用户能否根据自己的需要对C++已提供的运算符进行重载,赋予它们新的含义,使之一名多用。

   运算符重载的本质是函数重载。

   重载函数的一般格式如下:

函数类型 operator操作符名称 (形参列表)
{
    重载实体;
}

  operator 运算符名称 在一起构成了新的函数名。比如

const Complex operator+(const Complex &c1, const Complex &c2);

  我们会说,operator+ 重载了重载了运算符+。

 

2、操作符重载的规则

 

(1)C++不允许用户自己定义新的运算符,只能对已有的 C++运算符进行重载。

 

  例如,有人觉得 BASIC 中用“* *”作为幂运算符很方便,也想在 C++中将“**”定义为幂运算符,用“3* *5”表示 35,这是不行。

 

(2)C++允许重载的运算符

 

  C++中绝大部分运算符都是可以被重载的。

 

技术分享图片

 

   不能重载的运算符只有 4 个:

 

技术分享图片

 

  前两个运算符不能重载是为了保证访问成员的功能不能被改变,域运算符合sizeof 运算符的运算对象是类型而不是变量或一般表达式,不具备重载的特征。

 

(3)重载不能改变运算符运算对象(即操作数)的个数。

 

  如,关系运算符“>”和“<”等是双目运算符,重载后仍为双目运算符,需要两个参数。运算符”+“,”-“,”*“,”&“等既可以作为单目运算符,也可以作为双目运算符,可以分别将它们重载为单目运算符或双目运算符。
(4)重载不能改变运算符的优先级别。

 

  例如”*“和”/“优先级高于”+“和”-“,不论怎样进行重载,各运算符之间的优先级不会改变。有时在程序中希望改变某运算符的优先级,也只能使用加括号的方法 强制改变重载运算符的运算顺序。

 

(5)重载不能改变运算符的结合性。

 

  如,复制运算符”=“是右结合性(自右至左),重载后仍为右结合性。

 

(6)重载运算符的函数不能有默认的参数

 

  否则就改变了运算符参数的个数,与前面第(3)点矛盾。

 

(7)重载的运算符必须和用户定义的自定义类型的对象一起使用,其参数至少应有一 个是类对象(或类对象的引用)。

 

  也就是说,参数不能全部是 C++的标准类型,以防止用户修改用于标准类型数据成 员的运算符的性质,如下面这样是不对的:

 

  复制代码 代码如下:

 

int operator + (int a,int b)

{
  return(a-b);

}

 

 

 

  原来运算符+的作用是对两个数相加,现在企图通过重载使它的作用改为两个数相 减。如果允许这样重载的话,如果有表达式 4+3,它的结果是 7 还是 1 呢?显然,这是 绝对要禁止的。

 

(8)用于类对象的运算符一般必须重载,但有两个例外,运算符”=“和运算符”&“不 必用户重载。

 

复制运算符”=“可以用于每一个类对象,可以用它在同类对象之间相互赋值。因 为系统已为每一个新声明的类重载了一个赋值运算符,它的作用是逐个复制类中的数据 成员地址运算符&也不必重载,它能返回类对象在内存中的起始地址。
(9)应当使重载运算符的功能类似于该运算符作用于标准类型数据时候时所实现的功能。

 

  例如,我们会去重载”+“以实现对象的相加,而不会去重载”+“以实现对象相减的功能,因为这样不符合我们对”+“原来的认知。

 

(10)运算符重载函数可以是类的成员函数,也可以是类的友元函数,还可以是既非类 的成员函数也不是友元函数的普通函数。

 

 

案例一:复数相加

普通方法实现复数相加

  利用全局函数实现:

#include <iostream>
using namespace std;

class Complex
{
public:
    Complex(int a,int b)
    {
        this->a = a;
        this->b = b;
    }

    void printComplex()
    {
        cout << "(" << this->a << "," << this->b << ")" << endl;
    }

    friend Complex complexAdd(Complex &c1, Complex&c2);
private:
    int a;//实部
    int b;//虚部
};

Complex complexAdd(Complex &c1, Complex&c2)
{
    Complex temp(c1.a + c2.a, c1.b + c2.b);
    return temp;
}

int main(void)
{
    Complex c1(1,2);
    Complex c2(3,4);

    c1.printComplex();
    c2.printComplex();

    Complex c3 = complexAdd(c1, c2);
    c3.printComplex();

    return 0;
}

  利用成员函数实现:

#include <iostream>
using namespace std;

class Complex
{
public:
    Complex(int a,int b)
    {
        this->a = a;
        this->b = b;
    }

    void printComplex()
    {
        cout << "(" << this->a << "," << this->b << ")" << endl;
    }
    Complex complexAdd(Complex&another)
    {
        Complex temp(this->a + another.a, this->b + another.b);
        return temp;
    }

private:
    int a;//实部
    int b;//虚部
};

int main(void)
{
    Complex c1(1,2);
    Complex c2(3,4);

    c1.printComplex();
    c2.printComplex();

    Complex c3=c1.complexAdd(c2);
    c3.printComplex();

    return 0;
}

操作符重载方法实现复数相加:

   利用全局函数实现:

#include <iostream>
using namespace std;

class Complex
{
public:
    Complex(int a,int b)
    {
        this->a = a;
        this->b = b;
    }

    void printComplex()
    {
        cout << "(" << this->a << "," << this->b << "i)" << endl;
    }

    friend Complex operator+(Complex &c1, Complex &c2);

private:
    int a;//实部
    int b;//虚部
};

Complex operator+(Complex &c1, Complex &c2)
{
    Complex temp(c1.a + c2.a, c1.b + c2.b);
    return temp;
}

int main(void)
{
    Complex c1(1,2);
    Complex c2(3,4);

    c1.printComplex();
    c2.printComplex();

    Complex c3 = c1 + c2;//等同于Complex c3=operator+(c1, c2);
    c3.printComplex();

    return 0;
}

  利用成员函数实现:

#include <iostream>
using namespace std;

class Complex
{
public:
    Complex(int a,int b)
    {
        this->a = a;
        this->b = b;
    }

    void printComplex()
    {
        cout << "(" << this->a << "," << this->b << "i)" << endl;
    }

    Complex operator+(Complex &another)
    {
        Complex temp(this->a + another.a, this->b + another.b);
        return temp;
    }

private:
    int a;//实部
    int b;//虚部
};


int main(void)
{
    Complex c1(1,2);
    Complex c2(3,4);

    c1.printComplex();
    c2.printComplex();

    Complex c3 = c1 + c2;//等同于Complex c3=c1.operator+(c2);
    c3.printComplex();

    return 0;
}

 

 

#include <iostream>
using namespace std;

class Complex
{
public:
    Complex(int a, int b)
    {
        this->a = a;
        this->b = b;
    }

    void printComplex()
    {
        cout << "(" << this->a << "," << this->b << "i)" << endl;
    }

    friend Complex & operator+=(Complex &c1,Complex &c2);

private:
    int a;//实部
    int b;//虚部
};

Complex & operator+=(Complex &c1,Complex &c2)
{
    c1.a += c2.a;
    c1.b += c2.b;

    return c1;
}

int main(void)
{
    Complex c1(1, 2);
    Complex c2(3, 4);

    c1.printComplex();//(1, 2i)    
    c2.printComplex();//(3, 4i)

    (c1 += c2) += c2;
    c1.printComplex();//(7, 10i)
    c2.printComplex();//(3, 4i)

    return 0;
}

 

 

#include <iostream>
using namespace std;

class Complex
{
public:
    Complex(int a, int b)
    {
        this->a = a;
        this->b = b;
    }

    void printComplex()
    {
        cout << "(" << this->a << "," << this->b << "i)" << endl;
    }

    Complex& operator+=(Complex &another)
    {
        this->a += another.a;
        this->b += another.b;

        return *this;
    }

private:
    int a;//实部
    int b;//虚部
};


int main(void)
{
    Complex c1(1, 2);
    Complex c2(3, 4);

    c1.printComplex();//(1, 2i)    
    c2.printComplex();//(3, 4i)

    (c1 += c2) += c2;
    c1.printComplex();//(7, 10i)
    c2.printComplex();//(3, 4i)

    return 0;
}

 

类和对象(17)—— 操作符重载

标签:否则   namespace   ons   不同   技术分享   float   相减   语法   运算符重载   

原文地址:https://www.cnblogs.com/yuehouse/p/9818754.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!