C++学习-运算符重载

    xiaoxiao2021-04-15  31

    本文的目的主要是总结以下几点:

    (1)我们为什么需要运算符重载?(2)运算符重载实现方式有哪些?各有什么好处?(3)这些方式的比较?

    1、操作符重载概念

    同函数重载一样,算数操作符重载能够带给我们操作不同数据类型的方法,包括你自己定义的类。

    2、操作符重载实现方式

    我们日常最常用的就是加、减、乘、除,而它们的性质又有些相似。所以,它们的运算符实现方式也有些相似。 共有三种实现方式:

    (1)成员函数方法(2)友邻函数方法(3)普通函数方法

    3、友邻函数重载操作符

    首先,我们介绍怎样使用友邻函数定义操作符重载。看下面的代码:

    #include <iostream> class Cents { private: int m_cents; public: Cents(int cents) { m_cents = cents; } // 使用友邻函数实现 Cents + Cents friend Cents operator+(const Cents &c1, const Cents &c2); // 使用友邻函数实现 Cents - Cents friend Cents operator-(const Cents &c1, const Cents &c2); int getCents(void) const { return m_cents; } }; // 注意: 这个函数不是成员函数! Cents operator+(const Cents &c1, const Cents &c2) { // 使用 Cents 的构造函数 和通用 operator+(int, int) // 我们可以直接操作类成员变量 m_cents,因为是友邻函数 // 临时对象 return Cents(c1.m_cents + c2.m_cents); } // 注意: 这个函数不是成员函数! // 实现方式与加法相同 Cents operator-(const Cents &c1, const Cents &c2) { return Cents(c1.m_cents - c2.m_cents); } int main() { Cents cents1(6); Cents cents2(8); Cents centsSum = cents1 + cents2; Cents centsSub = cents1 - cents2; std::cout << "I have " << centsSum.getCents() << " cents." << std::endl; std::cout << "I have " << centsSub.getCents() << " cents." << std::endl; system("Pause"); }

    4、普通函数重载操作符

    #include <iostream> class Cents { private: int m_cents; public: Cents(int cents) { m_cents = cents; } int getCents() const { return m_cents; } }; // 注意:该函数既不是成员函数,也不是友邻函数! Cents operator+(const Cents &c1, const Cents &c2) { return Cents(c1.getCents() + c2.getCents()); } int main() { Cents cents1(6); Cents cents2(8); Cents centsSum = cents1 + cents2; std::cout << "I have " << centsSum.getCents() << " cents." << std::endl; return 0; }

    5 成员函数重载操作符

    使用成员函数实现操作符与友邻函数的实现方式非常相似。要满足下面三个条件: (1)重载操作符必须被添加为一个成员函数的左操作数; (2)左操作数成为隐含的this指针指向的对象; (3)所有其它的操作数都是函数参数; 看下面的代码:

    #include <iostream> class Cents { private: int m_cents; public: Cents(int cents) { m_cents = cents; } // Overload Cents + int Cents operator+(int value); int getCents() { return m_cents; } }; // 注意:该函数是一个成员函数! // 因为this指针,所以友邻函数所有引用都可以去掉 Cents Cents::operator+(int value) { return Cents(m_cents + value); } int main() { Cents cents1(6); Cents cents2 = cents1 + 2; std::cout << "I have " << cents2.getCents() << " cents.\n"; return 0; }

    6、比较总结

    6.1 普通函数方式和友邻函数方式

    通常情况下,如果有可能使用的已存在的成员函数,就优先使用普通函数实现(接触你的类内部的函数越少越好)。但是,不要为了替代友邻函数而添加额外的函数去实现普通函数重载操作符。

    6.2 友邻函数和成员函数的比较

    在编写代码的时候,我们该怎么选择呢?

    首先,并不是所有的操作符都可以使用友邻函数重载

    赋值 (=),下标([]),函数调用(()),成员选择(->)操作符必须被重载为成员函数,因为C++语言就是这样规定的。

    其次,所有的操作符也都不可以被重载为成员函数

    看下面的代码:

    #include <iostream> class Point { private: double m_x, m_y, m_z; public: Point(double x=0.0, double y=0.0, double z=0.0): m_x(x), m_y(y), m_z(z) { } friend std::ostream& operator<< (std::ostream &out, const Point &point); }; std::ostream& operator<< (std::ostream &out, const Point &point) { // 因为operator << 是Point类的友邻,所以我们可以直接访问其成员 out << "Point(" << point.m_x << ", " << point.m_y << ", " << point.m_z << ")"; return out; }

    在上面的代码中,operator<<不能被重载为成员函数。为什么呢?因为重载的操作符必须是成员的左操作数。在该例中,左操作数是对象的类型std::ostream。std::ostream是标准库的一部分。所以,我们不能修改类声明,将std::ostream添加为重载操作符。 所以,只能用友邻函数实现<<重载。 相似的,尽管我们能够重载 operator+(Cents, int) 为成员函数,正如我们上面做的,但是我们不能将其重载为成员函数,因为int不是我们能够添加成员的类。 通常,如果左操作符既不是类(如int),也不是我们能修改的类(如:std::ostream),我们不能使用成员重载。

    总结如下:

    (1)如果重载赋值 (=),下标([]),函数调用(()),成员选择(->)操作符,使用成员函数;(2)如果重载单目操作符,使用成员函数;(3)如果重载双目操作符,且左操作数能够修改,使用成员函数;(4)如果重载双目操作符,且左操作数不能够修改,使用普通函数或友邻函数;
    转载请注明原文地址: https://ju.6miu.com/read-671596.html

    最新回复(0)