【C++面向对象】五、运算符重载

文章目录

五、运算符重载

1、什么是运算符重载

运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。

运算符重载(operator overloading)只是一种“语法上的方便”,也就是它只是另一种函数调用的方式。

在c++中,可以定义一个新的运算符来处理类的数据。这种定义很像一个普通的函数定义,只是函数的名字由关键字operator及其紧随的运算符组成。差别仅此而已。它像其他函数一样也是一个函数,当编译器遇到适当的模式时,就会调用这个函数。

语法:

        定义重载的运算符就像定义函数,只是该函数的名字是operator@,这里的@代表了被重载的运算符。函数的参数个数取决于两个因素:

        运算符是一元(一个参数)还是二元(两个参数);

        运算符被定义为全局函数(对于一元是一个参数,对于二元是两个参数)还是成员函数(对于一元没有参数,对于二元是一个参数–此时该类的对象用作左耳参数)

注意:

    有些人很容易滥用运算符重载。它确实是一个有趣的工具。但是应该注意,它仅仅是一种语法上的方便而已,是另外一种函数调用的方式。从这个角度来看,只有在能使涉及类的代码更易写,尤其是更易读时才有理由重载运算符。如果不是这样,就改用其他更易用,更易读的方式。

2、可重载的运算符

几乎所有的运算符都可以重载,但运算符重载的使用时相当受限制的。特别是不能改变运算符优先级,不能改变运算符的参数个数。 这样的限制有意义,否则,所有这些行为产生的运算符只会混淆而不是澄清语意。

在这里插入图片描述

3、运算符重载:+

class Point {
public:
    // 定义属性
    int x;
    int y;

    // 构造函数
    Point(): x(0), y(0) {}
    Point(int x, int y): x(x), y(y) {}

    // 加法运算符重载
    Point operator+(const Point& p) const {
        return {x + p.x, y + p.y};
    }
};

// 全局函数实现减法运算符重载
Point operator-(const Point& p1, const Point& p2) {
    return {p1.x - p2.x, p1.y - p2.y};
}

int main() {

    Point p1(10, 20);
    Point p2(15, 25);

    Point res = p1 + p2;
    cout << "res.x = " << res.x << ", res.y = " << res.y << endl;

    Point res2 = p1 - p2;
    cout << "res2.x = " << res2.x << ", res2.y = " << res2.y << endl;

    return 0;
}

4、运算符重载:++

class Point {
public:
    // 定义属性
    int x;
    int y;

    // 定义构造函数,用来初始化属性
    Point(): x(0), y(0) {}
    Point(int x, int y): x(x), y(y) {}

    // 运算符前置,先运算、后取值
    Point operator++() {
        x++;
        y++;
        return *this;
    }

    // 在类内实现的运算符重载,运算符后置
    Point operator++(int) {
        // 先创建一个对象,记录原来的值
        Point tmp = *this;
        // 属性自增
        x++;
        y++;
        // 返回之前记录的值
        return tmp;
    }
};

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

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

int main() {

    Point p1(10, 20);
    Point p2(15, 25);

    Point res1 = ++p1;
    cout << "res1.x = " << res1.x << ", res1.y = " << res1.y << endl;
    cout << "p1.x = " << p1.x << ", p1.y = " << p1.y << endl;

    Point res2 = p2++;
    cout << "res2.x = " << res2.x << ", res2.y = " << res2.y << endl;
    cout << "p2.x = " << p2.x << ", p2.y = " << p2.y << endl;

    return 0;
}

5、运算符重载:<<

class Point {
    friend ostream& operator<<(ostream& os, const Point& p);
public:
    // 定义属性
    int x;
    int y;

    // 定义构造函数,用来初始化属性
    Point(): x(0), y(0), privateField(0) {}
    Point(int x, int y): x(x), y(y), privateField(0) {}

private:
    int privateField;
};

// 在类外定义运算符重载,全局函数
// 我希望在这里能够将Point类中的私有属性也拼接起来,因此需要做成友元
ostream& operator<<(ostream& os, const Point& p) {
    os << "x = " << p.x << ", y = " << p.y << ", privateField = " << p.privateField;
    return os;
}

int main() {
    Point p1(10, 20);
    cout << "p1: " << p1 << endl;

    return 0;
}

6、运算符重载:=

class Person {
public:
    int age;
    int score;
    int* p;

    Person(): age(0), score(0), p(nullptr) {}

    Person(const Person& person) {
        cout << "拷贝构造函数执行了" << endl;
        age = person.age;
        score = person.score;
        p = new int(*person.p);
    }

    // 重载赋值运算符
    Person& operator=(const Person& person) {
        cout << "重载赋值运算符执行了" << endl;
        age = person.age;
        score = person.score;
        p = new int(*person.p);
        return *this;
    }

    ~Person() {
        cout << "析构函数执行了" << endl;
        if (p == nullptr) {
            delete p;
            p = nullptr;
        }
    }
};

int main() {

    // 创建一个对象
    Person p1;
    p1.age = 18;
    p1.score = 99;
    p1.p = new int(100);
	
	// 在这里, 虽然是等号运算符, 但是p2对象还没有完成空间开辟、实例化, 那么在这里会调用拷贝构造函数, 而非重载的等号运算符
	Person p2 = p1;
	
	// 修改p2的属性值
	p2.age = 20;
	p2.score = 100;
	p2.p = new int(200);
	
	// 这里的p1已经开辟空间了, 这里就会触发重载的等号运算符
	p1 = p2;
	cout << p1.age << "," << p1.score << "," << p1.p << "=>" << *p1.p << endl;
	cout << p2.age << "," << p2.score << "," << p2.p << "=>" << *p2.p << endl;
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咖喱年糕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值