C++学习笔记总结练习:运算符重载两种方式

运算符重载的两种方式

1 基本概念

基础

  • 运算符时具有特殊名字的函数:由关键字operator和气候定义的运算符共同组成。

  • 可以被重载的运算符

C++学习笔记总结练习:运算符重载两种方式_第1张图片

方式

  1. 将运算符重载为类的成员函数
  2. 重载运算符函数,并声明为类的友元

规则

  1. 重载后的运算符必须至少有一个操作数是用户定义的类型,这是为了防止程序员为标准类型重载运算符,可以确保程序正确运行。

  2. 不能修改运算符的优先级,不能违反运算符原本的运算规则。例如在重载加号时,不能提供两个形参(友元除外),例如下面的这种重载方式就是不被允许的;因为加法是一种双目运算符。在重载为类的成员函数后,加法运算的第一项应该是调用函数的一个对象。所以在运算符重载时,参数表中的参数数目应该是重载运算符的操作数减1。

Time operator+(const Time &t1,const Time &t2) const;
  1. 不能创造新的运算符,例如不能定义operator**()运算符;
  2. 不能重载以下运算符;
.:成员运算符
.*:成员指针运算符
:: :作用域运算符
?::条件运算符
siezof:sizeof运算符。
  1. 很多运算符可以通过成员或者非成员函数进行重载,但是以下四种只能通过成员函数进行重载;
=:赋值运算符;
( ):函数调用运算符;
[ ]: 下标运算符
->:通过指针方位类成员的运算符。
  1. 自增运算符(++)与自减运算符(–)由于自增和自减运算符是单目运算符,在重载时应该是没有参数的,但是又有前置与后置之分,例如++i与i++。为了隽星区分,C++做了规定;
Time operator++()      //前置
Time operator++(int)   //后置

2 成员函数重载

成员函数重载格式

  • 将操作符重载为成员函数。
  • 此时类的对象作为操作符的第一个操作数。流输入输出运算符无法通过这样的方式重载,因为对象本身应该作为第二个操作数,只能通过友元函数的方式对操作进行重载。
class MyString{
public:
    // 重载等号运算符
    MyString& operator=(const MyString &b);
    // 重载+=运算符
    MyString& operator+=(const MyString &b);
}

3 友元重载

友元的格式

C++中友元有三种,分别是友元函数,友元类,友元成员函数,这里介绍的是友元函数。

  1. 创建友元函数的第一步是声明,友元函数的声明放在类的声明中,并且在前面加上friend关键字。例如;
friend ostream& operator<<(ostream &os, const Time &t);
  1. 第二步是定义友元,友元可以直接在声明的时候进行定义,即内联的定义。也可以定义在类外,定义在类外时,不需要加类作用域运算符,也不需要有friend关键字。
//友元在类外定义的时候,不需要添加friend;
ostream & operator<<(ostream &os, const Time &t)  
{
	os << "hours:" << t.hours << "  " << "mintues:" << t.mintues << "  ";
	return os;
}

友元使用

与普通的运算符重载成员函数一样,友元也可以直接调用

cout<

4 实例——MyString的实现

/* 
* C++ string 类的实现
* 1. 构造函数和析构函数
* 2. 字符串长度
* 3. 重载=运算符
* 4. 重载+=运算符
* 5. 重载<< >> 运算符
* 6. 重载比较运算符
* 7. 重载[]下标运算符
*/

#include 
#include 
using namespace std;

class MyString
{
private:
    char * str;
    int length;
public:
    // 长度
    int size ()const {
        return length;
    };
    char* getstr()const{
        return str;
    }
    // 默认构造函数
    MyString();
    // 字符串构造函数
    MyString(const char*);
    // 复制构造函数
    MyString(const MyString& b);

    // 重载等号运算符
    MyString& operator=(const MyString &b);
    // 重载+=运算符
    MyString& operator+=(const MyString &b);
    // 重载比较运算符
    bool operator<(const MyString &b);
    // 重载下标运算符
    char& operator[](const int &index) const ;
    // 重载输入输出操作
    friend ostream& operator<<(ostream& ,const MyString &b);
    ~MyString();
};

MyString::MyString()
{
    str = new char[1];
    str[0]='\0';
    length = 0;
}

MyString::MyString(const char* b){
    if(b){
        length = strlen(b);
        str = new char[length+1];
        strcpy(str,b);
    }
    else{
        MyString();
    }
}
MyString::MyString(const MyString&b){
    length = b.size();
    if(length>0)
    str = new char[length+1];
    else
    MyString();
}

MyString& MyString::operator=(const MyString &b){
    if(&b == this){
        return *this;
    }
    delete[] str;
    length = b.size();
    str = new char[length + 1];
    strcpy(str,b.getstr());
    return *this;
}

MyString& MyString::operator+=(const MyString&b){
    if(b.size()==0){
        return *this;
    }
    char* temp = new char[length+b.length+1];
    strcpy(temp,str);
    strcat(temp,b.getstr());
    delete[] str;
    str = temp;
    return *this;
}

char& MyString::operator[](const int &index)const {
    if(index>length)return str[length];
    return str[index];
}

bool MyString::operator<(const MyString &b){
    for(int i=0;ib.size())return false;
        if(b[i]>str[i])return true;
        if(b[i]

5 实例——complex的实现

#include 
using namespace std;
class complex{
public:
    complex(double real = 0.0, double imag = 0.0): m_real(real), m_imag(imag){ };
public:
    friend complex operator+(const complex & A, const complex & B);
    friend complex operator-(const complex & A, const complex & B);
    friend complex operator*(const complex & A, const complex & B);
    friend complex operator/(const complex & A, const complex & B);
    friend istream & operator>>(istream & in, complex & A);
    friend ostream & operator<<(ostream & out, complex & A);
private:
    double m_real;  //实部
    double m_imag;  //虚部
};
//重载加法运算符
complex operator+(const complex & A, const complex &B){
    complex C;
    C.m_real = A.m_real + B.m_real;
    C.m_imag = A.m_imag + B.m_imag;
    return C;
}
//重载减法运算符
complex operator-(const complex & A, const complex &B){
    complex C;
    C.m_real = A.m_real - B.m_real;
    C.m_imag = A.m_imag - B.m_imag;
    return C;
}
//重载乘法运算符
complex operator*(const complex & A, const complex &B){
    complex C;
    C.m_real = A.m_real * B.m_real - A.m_imag * B.m_imag;
    C.m_imag = A.m_imag * B.m_real + A.m_real * B.m_imag;
    return C;
}
//重载除法运算符
complex operator/(const complex & A, const complex & B){
    complex C;
    double square = A.m_real * A.m_real + A.m_imag * A.m_imag;
    C.m_real = (A.m_real * B.m_real + A.m_imag * B.m_imag)/square;
    C.m_imag = (A.m_imag * B.m_real - A.m_real * B.m_imag)/square;
    return C;
}
//重载输入运算符
istream & operator>>(istream & in, complex & A){
    in >> A.m_real >> A.m_imag;
    return in;
}
//重载输出运算符
ostream & operator<<(ostream & out, complex & A){
    out << A.m_real <<" + "<< A.m_imag <<" i ";;
    return out;
}
int main(){
    complex c1, c2, c3;
    cin>>c1>>c2;
    c3 = c1 + c2;
    cout<<"c1 + c2 = "<//------mytime.h
#ifndef MYTIME_H
#define MYTIME_H
#include 
 
using namespace std;
 
class Time
{
	//----------私有成员,类中的成员默认是私有的
private:
	int hours;
	int mintues;
 
	//----------共有成员
public:
	Time();                                                       //默认构造函数
	Time(int h, int m = 0);                                       //显式构造函数
	Time(const Time &);                                           //拷贝构造函数
	~Time();                                                      //析构函数
	void AddMin(int m);
	void AddHour(int h);
 
	void reset(int h = 0, int m = 0);
 
	//------展示函数show()     
	void Time::show() const
	{
		cout << "hours:" << hours << "  " << "mintues:" << mintues << "  ";
	}
 
 
 
	Time operator+(const Time &t) const;                          //运算符重载
	
	Time operator-(const Time &t) const;
	Time operator*(double n) const;
	friend Time operator*(double n, const Time &t)                //友元;
	{
		return t*n;                                               //在这里又调用了重载运算符   operator*(double n) const;
	}                                                             //内联形式的定义;
 
 
 
	friend ostream & operator<<(ostream &os, const Time &t);     //一个双目运算符在重载时,如果是以友元的形式声明的,那么他有两个形参;如果是类的成员函数,那么他只有一个形参;
 
};
 
 
//-------时间重置,内联函数
inline void Time::reset(int h, int m)
{
	hours = h;
	mintues = m;
}

#endif


//--mytime.cpp
 
#include 
#include "mytime.h"
 
using namespace std;
 
//-------默认构造函数
Time::Time()
{
	hours = mintues = 0;
	cout << "调用默认构造函数" << endl;
}
 
//------显式的构造函数
Time::Time(int h, int m) :hours(h), mintues(m)
{
	cout << "调用显式构造函数" << endl;
}
 
//------拷贝构造函数
Time::Time(const Time &t)
{
	hours = t.hours;
	mintues = t.mintues;
	cout << "调用拷贝构造函数" << endl;
}
 
//------析构函数
Time::~Time()
{
	cout << "调用了析构函数" << endl;
}
 
//-------小时相加
void Time::AddHour(int h)
{
	hours += h;
}
 
//------分钟相加
void Time::AddMin(int m)
{
	mintues += m;
	hours += mintues / 60;
	mintues %= 60;
}
 
 
//------重载+号
Time Time::operator+(const Time &t) const
{
	Time sum;
	sum.mintues = mintues + t.mintues;
	sum.hours = hours + t.hours + sum.mintues / 60;
	sum.mintues = sum.mintues % 60;
	return sum;
}
 
//------重载-号
Time Time::operator-(const Time &t) const
{
	Time diff;
 
	int time1 = hours * 60 + mintues;
	int time2 = t.hours * 60 + t.mintues;
 
	diff.hours = (time1 - time2) / 60;
	diff.mintues = (time1 - time2) % 60;
 
	return diff;
}
 
//-------重载乘号
Time Time::operator*(double n) const
{
	Time result;
	long totalMintues = n*hours * 60 + n*mintues;
 
	result.hours = totalMintues / 60;
	result.mintues = totalMintues % 60;
 
	return result;
}
 
 
 
//-------友元输出操作符
ostream & operator<<(ostream &os, const Time &t)           //友元在类外定义的时候,不需要添加friend;
{
	os << "hours:" << t.hours << "  " << "mintues:" << t.mintues << "  ";
	return os;
}

//-----------------------
//main.cpp
//不用先生
//------------------------
#include 
#include "mytime.h"
 
using namespace std;
 
 
int main()
{
 
	{
		Time eat_breakfast(0, 45);
		Time eat_lunch(1, 0);
		Time eat_dinner(1, 30);
 
 
 
		Time swiming(0, 45);                   //非const对象,既可以调用const成员函数,也可以调用非const成员。
		const Time study(8, 5);                //const对象只能调用const成员函数。
 
 
		// study_cut_swim;
		Time study_cut_swim = study - swiming;      //调用运算符重载后的Time类的减号;
 
 
		Time Eat_time_day = eat_breakfast + eat_dinner + eat_lunch;    //调用了重载以后的加法;
 
		cout << "学习比游泳多花" << study_cut_swim << endl;           //调用友元输出运算符<<
		cout << "每周吃饭所花费的时间为" << (7 * Eat_time_day) << endl;  //调用了友元乘法以及输出运算符;
	}
 
 
 
	system("pause");
	return 0;
}

你可能感兴趣的:(嵌入式软件,c语言,c++,c++,学习,笔记)