C++学习(五)_运算符重载

重载运算符

首先我们来看重载运算符的定义:

重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。

在C++中支持的重载运算符有:

不支持的重载运算符:


重载运算符的规则

运算符重载为类的成员函数的一般语法形式为:
函数类型 operator 运算符(形参表)
{
函数体;
}
运算符重载为类的友元函数的一般语法形式为:
friend 函数类型 operator 运算符(形参表)
{
函数体;
}
其中,函数类型就是运算结果类型;operator是定义运算符重载函数的关键字;运算符是重载的运算符名称。

当运算符重载为类的成员函数时,函数的参数个数比原来的操作个数要少一个;

当重载为类的友元函数时,参数个数与原操作数个数相同。

原因是重载为类的成员函数时,如果某个对象使用重载了的成员函数,自身的数据可以直接访问,就不需要再放在参数表中进行传递,少了的操作数就是该对象本身。

而重载为友元函数时,友元函数对某个对象的数据进行操作,就必须通过该对象的名称来进行,因此使用到的参数都要进行传递,操作数的个数就不会有变化。

运算符重载的主要优点就是允许改变使用于系统内部的运算符的操作方式,以适应用户自定义类型的类似运算。

下面我们分别对+,-,++,--,<<运算符分别进行运算符重载,观察程序的结果。


例1:重载+,-

1.使用成员函数实现运算符+,-的重载
#include<iostream>

using namespace std;

class Point {
public:
    Point(int x = 0, int y = 0):x(x),y(y) {};
    Point operator+(Point p) {
        return Point(this->x + p.x, this->y + p.y);
    }
    Point operator-(Point p) {
        return Point(this->x - p.x, this->y - p.y);
    }
    void display() {
        cout << "(" << x << "," << y << ")";
    }

private:
    int x,y;
};

int main()
{
    Point p1(1, 1);
    Point p2(2, 2);
    //1.将友元函数注释,调用Point的成员函数实现 p1 + p2
    Point p3 = p1 + p2;

    cout << "p1:";//输出p1的值
    p1.display();
    cout << " + ";
    cout << "p2:";//输出p2的值
    p2.display();
    cout << " = ";
    cout << "p3:";//输出p3的值
    p3.display();
    cout << endl;

    Point p4 = p1 - p2;

    cout << "p1:";//输出p1的值
    p1.display();
    cout << " - ";
    cout << "p2:";//输出p2的值
    p2.display();
    cout << " = ";
    cout << "p4:";//输出p4的值
    p4.display();
    cout << endl;

    return 0;
}

程序输出:

根据运行结果我们可以看出程序成功的实现了p1+p2和p1-p2。


2.使用友元函数实现运算符+,-的重载
#include<iostream>

using namespace std;

class Point {
    friend Point operator+(Point p1, Point p2); //友元函数
    friend Point operator-(Point p1, Point p2);
public:
    Point(int x = 0, int y = 0):x(x),y(y) {};
    void display() {
        cout << "(" << x << "," << y << ")";
    }

private:
    int x,y;
};

//重载运算符实现
Point operator+(Point p1, Point p2) {
    return Point(p1.x + p2.x, p1.y + p2.y);
}

Point operator-(Point p1, Point p2) {
    return Point(p1.x - p2.x, p1.y - p2.y);
}

int main()
{
    Point p1(1, 1);
    Point p2(2, 2);
    //2.将成语函数注释,调用Point的友元函数实现 p1 + p2
    Point p3 = p1 + p2;

    cout << "p1:";//输出p1的值
    p1.display();
    cout << " + ";
    cout << "p2:";//输出p2的值
    p2.display();
    cout << " = ";
    cout << "p3:";//输出p3的值
    p3.display();
    cout << endl;

    Point p4 = p1 - p2;

    cout << "p1:";//输出p1的值
    p1.display();
    cout << " - ";
    cout << "p2:";//输出p2的值
    p2.display();
    cout << " = ";
    cout << "p4:";//输出p4的值
    p4.display();
    cout << endl;

    system("pause");

    return 0;
}

运行结果:


例2:重载++,--

1.使用成员函数重载++
#include<iostream>

using namespace std;

class Point {

public:
    Point(int x = 0, int y = 0):x(x),y(y) {};
    Point & operator++() {    //对运算符++(前置)进行重载
        this->x++;
        this->y++;
        return *this;
    }
    Point operator++(int) {  //对运算符++(后置)进行重载
        Point p = *this;
        this->x++;
        this->y++;
        return p;
    }
    void display() {   //输出点
        cout << "(" << x << "," << y << ")" << endl << endl;
    }

private:
    int x,y;
};

int main()
{
    Point p(1, 1);
    cout << "p :";
    p.display();

        //p++
    cout << "------ p++ ------" << endl; 

    Point p1 = p++;
    cout << "p1:";
    p1.display();

    cout << "p :";
    p.display();

    cout << "------ p++ ------" << endl << endl;

    cout << "p :";
    p.display();

        //++p
    cout << "------ ++p ------" << endl;

    Point p2 = ++p;
    cout << "p2:";
    p2.display();

    cout << "p :";
    p.display();

    cout << "------ ++p ------" << endl << endl;

    system("pause");

    return 0;
}

运行结果:


2.使用成员函数重载--
#include<iostream>

using namespace std;

class Point {

public:
    Point(int x = 0, int y = 0):x(x),y(y) {};
    Point& operator--() {     //对运算符--(前置)进行重载
        this->x--;
        this->y--;
        return *this;
    }
    Point operator--(int) {    //对运算符--(后置)进行重载
        Point p = *this;
        this->x--;
        this->y--;
        return p;
    }
    void display() {
        cout << "(" << x << "," << y << ")" << endl << endl;
    }

private:
    int x,y;
};

int main()
{
    Point p(1, 1);
    cout << "p :";
    p.display();

        //p--
    cout << "------ (p--) ------" << endl;

    Point p1 = p--;
    cout << "p1:";
    p1.display();

    cout << "p :";
    p.display();

    cout << "------ (p--) ------" << endl << endl;

    cout << "p :";
    p.display();

    //--p
        cout << "------ (--p) ------" << endl;

    Point p2 = --p;
    cout << "p2:";
    p2.display();

    cout << "p :";
    p.display();

    cout << "------ (--p) ------" << endl << endl;

    system("pause");

    return 0;
}

运行结果:


3.使用友元函数重载++
#include<iostream>

using namespace std;

class Point {
    friend Point& operator++(Point& p);     //友元函数
    friend Point operator++(Point& p, int);
public:
    Point(int x = 0, int y = 0) :x(x), y(y) {};
    void display() {
        cout << "(" << x << "," << y << ")" << endl << endl;
    }

private:
    int x, y;
};

Point& operator++(Point &p) {
    p.x++;
    p.y++;
    return p;
}

Point operator++(Point &p, int) {
    Point temp = p;
    p.x++;
    p.y++;
    return temp;
}

int main()
{
    Point p(1, 1);
    cout << "p :";
    p.display();

        //p++
    cout << "------ p++ ------" << endl;

    Point p1 = p++;
    cout << "p1:";
    p1.display();

    cout << "p :";
    p.display();

    cout << "------ p++ ------" << endl << endl;

    cout << "p :";
    p.display();

        //++p
    cout << "------ ++p ------" << endl;

    Point p2 = ++p;
    cout << "p2:";
    p2.display();

    cout << "p :";
    p.display();

    cout << "------ ++p ------" << endl << endl;

    system("pause");

    return 0;
}

运行结果:


4.使用友元函数重载--
#include<iostream>

using namespace std;

class Point {
    friend Point& operator--(Point& p);   //友元函数
    friend Point operator--(Point& p, int);
public:
    Point(int x = 0, int y = 0) :x(x), y(y) {};
    void display() {
        cout << "(" << x << "," << y << ")" << endl << endl;
    }

private:
    int x, y;
};

Point& operator--(Point& p) {
    p.x--;
    p.y--;
    return p;
}

Point operator--(Point& p, int) {
    Point temp = p;
    p.x--;
    p.y--;
    return temp;
}

int main()
{
    Point p(1, 1);
    cout << "p :";
    p.display();

        //p--
    cout << "------ (p--) ------" << endl;

    Point p1 = p--;
    cout << "p1:";
    p1.display();

    cout << "p :";
    p.display();

    cout << "------ (p--) ------" << endl << endl;

    cout << "p :";
    p.display();

        //--p
    cout << "------ (--p) ------" << endl;

    Point p2 = --p;
    cout << "p2:";
    p2.display();

    cout << "p :";
    p.display();

    cout << "------ (--p) ------" << endl << endl;

    system("pause");

    return 0;
}

运行结果:


例3:重载<<运算符实现对Point对象的输出

#include<iostream>

using namespace std;

class Point {
    friend ostream& operator<<(ostream & out, Point& p);    //友元函数
public:
    Point(int x = 0, int y = 0) :x(x), y(y) {};
private:
    int x, y;
};

ostream& operator<<(ostream & out,Point &p) {
    out << "(" << p.x << "," << p.y << ")";
    return out;
}

int main()
{
    Point p(1, 1);
    cout << "p:" << p;    //使用重载后的<<输出p

    system("pause");

    return 0;
}

运行结果:

根据运行结果我们可以看出程序通过<<输出了p的值。

此时我们想到:可不可以使用成员函数重载<<呢?

*使用成员函数重载<<运算符
#include<iostream>

using namespace std;

class Point {
public:
    Point(int x = 0, int y = 0) :x(x), y(y) {};
    void operator<<(ostream& out) {        //使用成员函数进行<<运算符重载
        out << "(" << this->x << "," << this->y << ")";
    }
private:
    int x, y;
};

int main()
{
    Point p(1, 1);
    p << cout;

    system("pause");

    return 0;
}

程序可以正常运行。

但是会出现一个问题,就是程序输出p时只能写成

p << cout

的形式。

因为函数的第一个参数是this指针,第二个参数才是我们传进去的 out,但是这与std中的cout使用习惯完全不符,我们的所打印变量是应该在cout的右边,如 cout<<d<<endl.

这样的重载和普通的函数没有两样,也就失去了重载函数的目的所在。

那么这样,我们便不可以把输出运算符的重载写成成员函数,写成成员函数去实现功能,能实现功能 但失去重载本身的意义。

所以我们应该在类外写重载函数,然后在对应的类中使用友元函数。

以上为我对C++重载运算符知识点的总结。

如有不对,敬请指正。

原文地址:https://www.cnblogs.com/meituanqishoualin/p/11747306.html

时间: 2024-11-01 22:03:59

C++学习(五)_运算符重载的相关文章

C++ Primer Plus学习笔记之运算符重载

C++ Primer Plus学习笔记之运算符重载 1,成员函数和友元函数选择的建议 下面我们先看两个例子: 成员函数重载 #include<iostream> using namespace std; class Complex { public: Complex(double r=0,double i=0) { re=r; im=i; } Complex operator+(const Complex& obj); Complex operator!(); void Display

12--C++_运算符重载

C++_运算符重载 什么是运算符的重载? 运算符与类结合,产生新的含义. 为什么要引入运算符重载? 作用:为了实现类的多态性(多态是指一个函数名有多种含义) 怎么实现运算符的重载? 方式:类的成员函数 或 友元函数(类外的普通函数) 规则:不能重载的运算符有.  和 .* 和 ?: 和 ::  和 sizeof 和 typeid 友元函数和成员函数的使用场合: 一般情况下,建议一元运算符使用成员函数,二元运算符使用友元函数 1.运算符的操作需要修改类对象的状态,则使用成员函数.如需要做左值操作数

C++学习笔记之运算符重载

一.运算符重载基本知识 在前面的一篇博文 C++学习笔记之模板(1)——从函数重载到函数模板 中,介绍了函数重载的概念,定义及用法,函数重载(也被称之为函数多态)就是使用户能够定义多个名称相同但特征标(参数列表)不同的函数,目的是在对不同类型的参数执行相同的操作时只用一个同名的函数. 运算符重载,就是使同一个运算符在面临不同类型的数据时作出不同的操作(函数重载是操作相同),就是让同一个运算符有多重功能.实际上我们经常用的许多运算符已被重载,例如,将*用于地址,将得到存储在这个地址中的值:但将它用

C++_基础_运算符重载2

内容: (1)只能用成员形式重载的运算符 (2)new/delete操作符的重载 (3)封装和继承的初识 (4)继承的特性 (5)子类及其函数的特性 (6)多重继承和虚继承 1.只能用成员形式重载的运算符(1)[] 下标操作符 (2)() 函数操作符(3)* -> 间接操作符 2.new/delete操作符的重载 注意: 如果需要在调用构造函数之前做一些初始化工作/在调用析构函数之后做一些善后工作,则可以通过new/delete运算符重载的函数来实现 3.封装和继承的初识3.1 概念(1)封装

scala学习手记7 - 运算符重载

从语法上来说scala是没有运算符的.之前的一节里也曾提到过scala的运算符实际上是方法名,如1 + 2实际上就是1.+(2).我们可以将之视为运算符,是因为scala的一个特性:如果方法的参数小于等于1个的话,那么"."和括号就都是可选的. scala的运算符重载指的就是重载+.-这样的符号--和C.java或者python等语言不一样,我们需要自己定义这些符号如何实现. 下面看一个"+"运算符实现的例子.这里定义了一个Complex类,Complex指的是复数

PKU C++程序设计实习 学习笔记4 运算符重载

第四章 运算符重载 4.1 运算符重载的基本概念 1. 运算符 2. 自定义数据类型与运算符重载 C++提供了数据抽象的手段:用户自己定义数据类型 -- 类 ? 调用类的成员函数->操作它的对象 类的成员函数->操作对象时,很不方便 ? 在数学上,两个复数可以直接进行+/-等运算 Vs. 在C++中,直接将+或-用于复数是不允许的 3. 运算符重载 对抽象数据类型也能够直接使用C++提供的运算符 ? 程序更简洁 ? 代码更容易理解 运算符重载 ? 对已有的运算符赋予多重的含义 ? 使同一运算符

C++_运算符重载 总结

什么是运算符的重载? 运算符与类结合,产生新的含义. 为什么要引入运算符重载? 作用:为了实现类的多态性(多态是指一个函数名有多种含义) 怎么实现运算符的重载? 方式:类的成员函数 或 友元函数(类外的普通函数) 规则:不能重载的运算符有 .  和 .* 和 ?: 和 ::  和 sizeof 友元函数和成员函数的使用场合:一般情况下,建议一元运算符使用成员函数,二元运算符使用友元函数 1.运算符的操作需要修改类对象的状态,则使用成员函数.如需要做左值操作数的运算符(如=,+=,++) 2.运算

新标准C++程序设计读书笔记_运算符重载

形式 返回值类型 operator 运算符(形参表) { …… } 运算符重载 (1)运算符重载的实质是函数重载(2)可以重载为普通函数,也可以重载为成员函数 1 class Complex 2 { 3 public: 4 double real,imag; 5 Complex( double r = 0.0, double i= 0.0 ):real(r),imag(i) { } 6 Complex operator-(const Complex & c); 7 }; 8 9 Complex

C++程序设计_第9章_运算符重载及流类库

例9.1 完整实现str类的例子. 1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include <iostream> 4 #include <string> 5 6 using namespace std; 7 8 class str 9 { 10 private: 11 char *st; 12 public: 13 str(char *s);//使用字符指针的构造函数 14 str(str& s);//使用对象引用的构造函数 15 st