📜  C++中的运算符重载

📅  最后修改于: 2021-05-30 19:58:22             🧑  作者: Mango

在C++中,我们可以使运算符为用户定义的类工作。这意味着C++能够为运算符提供数据类型的特殊含义,这种能力称为运算符重载。
例如,我们可以在类似String的类中重载运算符’+’,以便仅使用+就可以连接两个字符串。
算术运算运算符可能会重载的其他示例类是复数,小数,大整数等。

一个简单而完整的例子

#include
using namespace std;
  
class Complex {
private:
    int real, imag;
public:
    Complex(int r = 0, int i =0)  {real = r;   imag = i;}
      
    // This is automatically called when '+' is used with
    // between two Complex objects
    Complex operator + (Complex const &obj) {
         Complex res;
         res.real = real + obj.real;
         res.imag = imag + obj.imag;
         return res;
    }
    void print() { cout << real << " + i" << imag << endl; }
};
  
int main()
{
    Complex c1(10, 5), c2(2, 4);
    Complex c3 = c1 + c2; // An example call to "operator+"
    c3.print();
}

输出:

12 + i9

运算符功能和普通功能有什么区别?
操作员功能与普通功能相同。唯一的区别是,运算符函数的名称始终运算符关键字后跟的运算符和运算符功能符号被用于相应的运算符时被调用。
以下是全局运算符函数的示例。

#include
using namespace std;
  
class Complex {
private:
    int real, imag;
public:
    Complex(int r = 0, int i =0)  {real = r;   imag = i;}
    void print() { cout << real << " + i" << imag << endl; }
  
// The global operator function is made friend of this class so
// that it can access private members
friend Complex operator + (Complex const &, Complex const &);
};
  
  
Complex operator + (Complex const &c1, Complex const &c2)
{
     return Complex(c1.real + c2.real, c1.imag + c2.imag);
}
  
  
int main()
{
    Complex c1(10, 5), c2(2, 4);
    Complex c3 = c1 + c2; // An example call to "operator+"
    c3.print();
    return 0;
}

我们可以让所有运算符超载吗?
除了少数操作员之外,几乎所有运算符都可以重载。以下是不能重载的运算符的列表。

. (dot) 
   :: 
   ?: 
   sizeof 

为什么不能。 (点),::,?:和sizeof是否被重载?
请参阅此以获取Stroustrup自己的答案。

有关运算符重载的要点
1)为了使运算符重载起作用,至少一个操作数必须是用户定义的类对象。

2)赋值运算符:编译器会自动为每个类创建一个默认的赋值运算符。默认的赋值运算符确实将右侧的所有成员分配到左侧,并且在大多数情况下都可以正常工作(此行为与复制构造函数相同)。有关更多详细信息,请参见此内容。

3)转换运算符:我们还可以编写可用于将一种类型转换为另一种类型的转换运算符。

#include 
using namespace std;
class Fraction
{
    int num, den;
public:
    Fraction(int n,  int d) { num = n; den = d; }
  
    // conversion operator: return float value of fraction
    operator float() const {
        return float(num) / float(den);
    }
};
  
int main() {
    Fraction f(2, 5);
    float val = f;
    cout << val;
    return 0;
}

输出:

0.4

重载的转换运算符必须是成员方法。其他运算符可以是成员方法或全局方法。

4)任何可以用单个参数调用的构造函数都可以用作转换构造函数,这意味着它也可以用于隐式转换为正在构造的类。

#include 
using namespace std;
  
class Point
{
private:
    int x, y;
public:
    Point(int i = 0, int j = 0) {
        x = i;   y = j;
    }
    void print() {
        cout << endl << " x = " << x << ", y = " << y;
    }
};
  
int main() {
    Point t(20, 20);
    t.print();
    t = 30;   // Member x of t becomes 30
    t.print();
    return 0;
}

输出:

x = 20, y = 20
 x = 30, y = 0

我们很快将讨论一些重要运算符的重载,例如new,delete,逗号,函数调用,箭头等。

运算符重载测验

参考:
http://en.wikipedia.org/wiki/Operator_overloading

要从最佳影片策划和实践问题去学习,检查了C++基础课程为基础,以先进的C++和C++ STL课程基础加上STL。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程”