首页天道酬勤(P22)运算符重载:运算符重载 ,成员函数重载 ,非成员函数重载 ,运算符重载规则

(P22)运算符重载:运算符重载 ,成员函数重载 ,非成员函数重载 ,运算符重载规则

admin 03-18 14:31 19次浏览

文章目录

1.运算符重载

2.成员函数重载

3.重载非成员函数

4.符合重载规则的操作

1.运算符重载

运算符重载允许标准运算符(如运算符)+、—、*、/、<、>等)应用于自定义数据类型的对象

直观自然,可以提高程序的可读性

它反映了C++的可扩展性

运算符重载只是语法上的便利,是另一种调用函数的方式

运算符重载本质上是函数重载

不要滥用重载,因为它只是语法上的方便,所以只有当涉及的代码更容易写,特别是更容易读取时,才有必要重载

2.成员函数重载

成员函数原型格式:

函数类型 operator 运算符(参数表);

1.

成员函数定义的格式:

函数类型 类名::operator 运算符(参数表){

    函数体;

  }

函数原型的格式:

friend 函数类型 operator 运算符(参数表);

1.

友元函数定义的格式:

friend 函数类型 类名::operator 运算符(参数表){

    函数体;

}


eg:实现一个复数类,22cpp\01.cpp

#include "Complex.h"


int main(void)

{

    Complex c1(3, 5);

    Complex c2(4, 6);


    // c1.Add(c2);

    // c1.Display();


    //若成员函数或者友元函数都有,VS2008会先运行成员函数重载的函数,但是在VC6中,这俩不能共存

    //如果以成员函数的方式重载,等价于c1.operator+(c2)

    //如果以友元函数的方式重载,等价于operator+(c1+c2),该operator+的作用域是全局的,不是类作用域

    Complex c3 = c1 + c2;   

    c1.Display();

    c2.Display();

    c3.Display(); 

}


类声明及定义

22cpp\Complex.h

#ifndef _CONPLEX_H_

#define _CONPLEX_H_


class Complex

{

public:

    Complex(int real, int imag);

    Complex();

    ~Complex();


    Complex& Add(const Complex& other);

    void Display() const;


    Complex operator+(const Complex& other);


    //友元函数重载,比成员函数重载多一个参数,因为友元函数不是类的成员,它没有隐含一个自身对象(第一个参数)

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


private:

    int real_;

    int imag_;

};


#endif /* _CONPLEX_H_ */


22cpp\Complex.cpp


#include "Complex.h"

#include <iostream>

using namespace std;

Complex::Complex(int real, int imag) : real_(real), imag_(imag)

{


}


Complex::Complex()

{


}


Complex::~Complex()

{


}

//返回的是自身的引用,所以不会调用拷贝构造函数

Complex& Complex::Add(const Complex& other)

{

    real_+=other.real_;

    imag_+=other.imag_;

    return *this;

}


//运算符重载本质上是函数重载

//Complex c3=c1+2;因为要将返回的对象赋值给c3,返回了一个新的对象,这里c1和c2对象是不发生改变的

//而上面的那个Add会将c1对象发生改变,所以不能返回*this

Complex Complex::operator+(const Complex& other)

{

    int r = real_ + other.real_;

    int i = imag_ + other.imag_;


    return Complex(r, i); 

}


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

{

    int r = c1.real_ + c2.real_;

    int i = c1.imag_ + c2.imag_;


    return Complex(r, i); 

}



void Complex::Display() const

{

    cout<<real_<<"+"<<imag_<<"i"<<endl;

}


测试:

c1.Add(c2);

c1.Display();


Complex c3 = c1 + c2;

c1.Display();

c2.Display();

c3.Display();

c1与c2都没有发生改变,只有c3变了

操作符合重载规则的操作

重载运算符不允许发明新的运算符。

无法改变操作对象的数量。

在重载运算符之后,其优先级和组合性不会改变。

无法重载的运算符:

一般而言,单目运算符最好重载为类的成员函数;双目运算符最好重载为类的友元函数。

下列双目运算符不能重载为类的友元函数:=、()、[]、->。

=计算符是双目计算符。调用时,类型不匹配,返回时类型不匹配,不直观,会破坏原计算符。

class Test

{

public:

  Test& operator=(const Test& other);

private:

  int x_;

};

Test t1;

Test t2;

t1=t2;//等价于t1.operator=(t2);


若是写成类的友元函数,Test是类D的派生类的话

class D : public Test

{

  friend  Test& operator=(Test& t1, const Test& t2);

};


Test& operator=(Test& t1, const Test& t2)

{

  t1.x_ = t2.x_;

  return t1;

}

D d;

Test t;

D = d//等价于D.operator=(d);会出现类型不匹配,返回时类型也不匹配


类型转换运算符只能以成员函数方式重载

流运算符只能以友元的方式重载


关于Linux下防火墙的总结 php -v不显示php版本号如何解决