第30课 操作符重载的概念

 1. 复数类需要解决的问题

——下面的复数解决方案是否可行?    

不可行+ 操作符只提供对C++ 基本数据类型的运算,不支持类的相加运算

      

【编程实验】复数的加法操作  30-1.cpp

#include <stdio.h>

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

    int getB()
    {
        return b;
    }
    
    friend Complex Add(const Complex& p1, const Complex& p2);  // 友元函数
};

Complex Add(const Complex& p1, const Complex& p2)
{
    Complex ret;

    ret.a = p1.a + p2.a;
    ret.b = p1.b + p2.b;

    return ret;
}

int main()
{
    Complex c1(1, 2);
    Complex c2(3, 4);
    Complex c3 = Add(c1, c2); // c1 + c2

    printf("c3.a = %d, c3.b = %d
", c3.getA(), c3.getB());

    return 0;
}

运行结果:

  

思考:Add 函数可以解决Complex 对象相加的问题,但是 Comples 是现实世界中确实存在的复数,并且复数在数学中的地位和普通的实数相同。  

为什么不让  +  操作符也支持复数相加呢?

 

2. 操作符重载

(1)C++中的重载能够扩展操作符的功能

(2)操作符的重载函数的方式进行,本质上是用特殊形式的函数扩展操作符的功能

(3)通过operator关键字可以定义特殊函数operator的本质通过函数重载操作符

(4)语法: Type operator Sign(const Type& p1, const Type& p2);  //Sign+-*

【编程实验】操作符重载初探

#include <stdio.h>

class Complex
{

private:

    int a;

    int b;

     

public:

    Complex(int a = 0, int b = 0)
    {

        this->a = a;

        this->b = b;

    }

     

    int getA(){return a;}

    int getB(){return b;}

   

     //方式一:通过全局普通的函数实现复数相加
    friend Complex Add(const Complex& p1, const Complex& p2);

   
    //方式二:通过全局函数重载“+”操作符实现复数相加
    friend Complex operator + (const Complex& p1, const Complex& p2);

};

 

//全局普通函数
Complex Add(const Complex& p1, const Complex& p2)
{

      Complex ret;

      ret.a = p1.a + p2.a;

      ret.b = p1.b + p2.b;

     

      return ret;

}

 

//全局重载操作符+
Complex operator + (const Complex& p1, const Complex& p2)
{

      Complex ret;

      ret.a = p1.a + p2.a;

      ret.b = p1.b + p2.b;

     

      return ret;

}

 

int main()
{

    Complex c1(1, 2);

    Complex c2(3, 4);

   

    //方式一的调用
    //Complex c3 = Add(c1, c2);  //方式一调用。缺点是无法写成:c1 + c2的形式;

   

    //方式二的调用
    //Complex c3 = operator+(c1, c2);//把“opertor+”当成函数名一样的调用

    Complex c3 = c1 + c2;        //更直观,本质上是调用“operator+”这个函数

   

    printf("c3.a = %d, c3.b = %d
",c3.getA(), c3.getB());


    return 0;

}

运行结果:

  

  

3. 可将操作符重载函数定义为类的成员函数

(1)比全局操作符重载函数少一个参数左操作数

(2)不需要依赖友元可以完成操作符重载

(3)编译器优先成员函数寻找操作符重载函数(截图)

【编程实验】成员函数重载操作符   30-3.cpp

#include <stdio.h>

class Complex
{

private:

    int a;

    int b;

     

public:

    Complex(int a = 0, int b = 0)

    {

        this->a = a;

        this->b = b;

    }

     

    int getA(){return a;}

    int getB(){return b;}

   

     //方式一:通过全局普通的函数实现复数相加
    friend Complex Add(const Complex& p1, const Complex& p2);

   

    //方式二:通过全局函数重载“+”操作符实现复数相加
    friend Complex operator + (const Complex& p1, const Complex& p2);

   

    //方式三:通过成员函数实现“+”操作符的重载
    Complex operator+(const Complex& p) //参数少了一个左操作数!
    {

        Complex ret;

        ret.a = this->a + p.a;

        ret.b = this->b + p.b;

       
        return ret;

    }

};

 

//全局普通函数
Complex Add(const Complex& p1, const Complex& p2)
{

      Complex ret;

      ret.a = p1.a + p2.a;

      ret.b = p1.b + p2.b;

     

      return ret;

}

 

//全局重载操作符+
Complex operator + (const Complex& p1, const Complex& p2)
{

      Complex ret;

      ret.a = p1.a + p2.a;

      ret.b = p1.b + p2.b;

     

      return ret;

}

 

int main()
{

    Complex c1(1, 2);

    Complex c2(3, 4);

   

    //方式一的调用
    //Complex c3 = Add(c1, c2);  //方式一调用。缺点是无法写成:c1 + c2的形式;

   

    //方式二的调用
    //Complex c3 = operator+(c1, c2);//把“opertor+”当成函数名一样的调用

    //Complex c3 = c1 + c2;        //更直观,本质上是调用“operator+”这个函数

   

    //方式三的调用
    //Complex c3 = c1.operator+(c2);//把“opertor+”当成函数名一样的调用
    Complex c3 = c1 + c2;          //优先选择成员函数,而不是全局的operator+    

   
    printf("c3.a = %d, c3.b = %d
",c3.getA(), c3.getB());


    return 0;

}

运行结果:

  

   

4. 小结

(1)操作符重载C++强大特性之一本质是通过函数扩展操作符的功能

(2)operator关键字是实现操作符重载关键

(3)操作符重载遵循相同的函数重载规则

(4)全局函数成员函数都可以实现对操作符的重载,但编译器优先选择通过成员函数实现的操作符重载函数

原文地址:https://www.cnblogs.com/hoiday/p/10092021.html