Operator Overloading in C++ - C++ 中的运算符重载

Operator Overloading in C++ - C++ 中的运算符重载

In C++, we can make operators to work for user defined classes. This means C++ has the ability to provide the operators with a special meaning for a data type, this ability is known as operator overloading.
在 C++ 中,我们可以使运算符为用户定义的类工作。这意味着 C++ 能够为运算符提供数据类型的特殊含义,这种能力称为运算符重载。

For example, we can overload an operator + in a class like String so that we can concatenate two strings by just using +.
例如,我们可以在 String 之类的类中重载运算符 +,以便仅使用 + 就可以连接两个字符串。

Other example classes where arithmetic operators may be overloaded are Complex Number, Fractional Number, Big Integer, etc.
算术运算符可能会重载的其他示例类是 Complex Number, Fractional Number, Big Integer, etc.。

1. A simple and complete example

//============================================================================
// Name        : operator overloading
// Author      : Yongqiang Cheng
// Version     : Version 1.0.0
// Copyright   : Copyright (c) 2019 Yongqiang Cheng
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>

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);

    // An example call to "operator+"
    Complex c3 = c1 + c2;
    c3.print();

    return 0;
}

12 + i9

2. What is the difference between operator functions and normal functions?

Operator functions are same as normal functions. The only differences are, name of an operator function is always operator keyword followed by symbol of operator and operator functions are called when the corresponding operator is used.
操作符函数与普通函数相同。唯一的区别是,运算符函数的名称始终是运算符关键字,后跟运算符的符号,并且在使用相应的运算符时会调用运算符函数。

Following is an example of global operator function.
以下是全局运算符函数的示例。

//============================================================================
// Name        : operator overloading
// Author      : Yongqiang Cheng
// Version     : Version 1.0.0
// Copyright   : Copyright (c) 2019 Yongqiang Cheng
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
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);
    // An example call to "operator+"
    Complex c3 = c1 + c2;
    c3.print();

    return 0;
}

12 + i9

3. Can we overload all operators?

Almost all operators can be overloaded except few. Following is the list of operators that cannot be overloaded.
除了少数操作符之外,几乎所有操作符都可以重载。以下是不能重载的运算符的列表。

   . (dot) 
   :: 
   ?: 
   sizeof 

4. Why can’t . (dot), ::, ?: and sizeof be overloaded?

  1. For operator overloading to work, at least one of the operands must be a user defined class object.
    为了使运算符重载起作用,至少一个操作数必须是用户定义的类对象。

  2. Assignment Operator: Compiler automatically creates a default assignment operator with every class. The default assignment operator does assign all members of right side to the left side and works fine most of the cases (this behavior is same as copy constructor). See this for more details.
    赋值运算符:编译器会自动为每个类创建一个默认的赋值运算符。默认的赋值运算符确实将右侧的所有成员分配到左侧,并且在大多数情况下都可以正常工作 (此行为与复制构造函数相同)。有关更多详细信息,请参见此内容。

  3. Conversion Operator: We can also write conversion operators that can be used to convert one type to another type.
    转换运算符:我们还可以编写可用于将一种类型转换为另一种类型的转换运算符。

//============================================================================
// Name        : operator overloading
// Author      : Yongqiang Cheng
// Version     : Version 1.0.0
// Copyright   : Copyright (c) 2019 Yongqiang Cheng
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
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

Overloaded conversion operators must be a member method. Other operators can either be member method or global method.
重载的转换运算符必须是成员方法。其他运算符可以是成员方法或全局方法。

  1. Any constructor that can be called with a single argument works as a conversion constructor, means it can also be used for implicit conversion to the class being constructed.
    可以用单个参数调用的任何构造函数都可以用作转换构造函数,这意味着它也可以用于隐式转换为正在构造的类。
//============================================================================
// Name        : operator overloading
// Author      : Yongqiang Cheng
// Version     : Version 1.0.0
// Copyright   : Copyright (c) 2019 Yongqiang Cheng
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
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();

    // Member x of t becomes 30
    t = 30;
    t.print();

    return 0;
}


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

We will soon be discussing overloading of some important operators like new, delete, comma, function call, arrow, etc.
我们将很快讨论一些重要运算符的重载,例如 new, delete, comma, function call, arrow 等。

1982 年,美国 AT&T 公司贝尔实验室的 Bjarne Stroustrup 博士在 C 语言的基础上引入并扩充了面向对象的概念,发明了—种新的程序语言。为了表达该语言与 C 语言的渊源关系,它被命名为 C++。Bjarne Stroustrup (本贾尼·斯特劳斯特卢普) 博士被尊称为 C++ 语言之父。

References

http://www.stroustrup.com/index.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Yongqiang Cheng

梦想不是浮躁,而是沉淀和积累。

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

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

打赏作者

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

抵扣说明:

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

余额充值