C++ 运算符重载

文章介绍了C++中的运算符重载,包括其目的、格式和调用方式。通过运算符重载,可以使得像+、-这样的运算符能应用于对象之间。重载后的运算符在编译时被替换为对应的函数调用。文章举例说明了+、-运算符的重载,指出重载为成员函数和全局函数时参数的区别,并强调了赋值运算符=的重载只能是成员函数,以及()运算符重载也仅能为成员函数,用于实现函数对象。
摘要由CSDN通过智能技术生成

1.基础知识

1.1 运算符重载的目的

如果不做特殊处理,C++ 的 +、-、*、/ 等运算符只能用于对基本类型的常量或变量进行运算,不能用于对象之间的运算。未经重载的运算符不能用于对象之间的运算。

运算符重载  是为了进行对象之间的运算,并且是同类型对象之间的运算。

运算符重载的实质是 编写以[operator 运算符]作为名称的函数。该函数可以作为类的成员函数,也可以作为普通的类外的函数。

1.2运算符重载的格式

不妨把这样的函数称为运算符函数。运算符函数的格式如下:

返回值类型  operator 运算符(形参表)
{
    ....
}

operator 运算符 (比如 operator +)这两个连起来的东西看做一个整体

1.3运算符重载后的调用

包含被重载的运算符的表达式 会被编译 成对运算符函数的调用,运算符的操作数成为函数调用时的实参,运算的结果就是函数的返回值。运算符可以被多次重载。

简而言之:重载后的运算符  在调用处的代码,编译时,被替换

有了对+的重载,编译器就将c=a+b理解为对运算符函数的调用,即c=operator+(a,b)

2. "+" ,"- "加号,减号 ,运算符的重载

注意:内的内部的运算符重载函数和类外部的不一样

重点:运算符重载为全局函数时,参数的个数等于运算符的目数(即操作数的个数);运算符重载为成员函数时,参数的个数等于运算符的目数减一。


#include <iostream>
using namespace std;
class Complex
{
    public:
    double real, imag;
    Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) { }
    Complex operator - (const Complex & c);
};

//类外部的运算符重载函数  不属于某个类 传入参数与目数相等
Complex operator + (const Complex & a, const Complex & b)
{   //下面语句为第12行
    return Complex(a.real + b.real, a.imag + b.imag); //第12行返回一个临时对象
}

//类内部的 运算符重载函数  传入参数比目数 少1 (需要调用自身的类的成员变量)
Complex Complex::operator - (const Complex & c)
{
    return Complex(real - c.real, imag - c.imag); //第16行返回一个临时对象
}

int main()
{
    Complex obj_a(10, 20), obj_b(5, 1), obj_c;

    obj_c = obj_a + obj_b; //等价于 obj_c = operator + (obj_a,obj_b);
    cout << obj_c.real << "," << obj_c.imag << endl;//15,21

	obj_c=obj_a-obj_b;//obj_a-obj_b等价于obj_a.operator - (b)
	cout << c.real << "," << obj_c.imag << endl;//5,19
    cout << (obj_a - obj_b).real << "," << (obj_a - obj_b).imag << endl; 
    //5,19 obj_a-obj_b等价于obj_a.operator - (obj_b)
    return 0;
}

类内部定义的运算符重载函数  具体执行时的细节

c=a-b;//a-b等价于a.operator - (b)    operator - (b)就是运算符重载函数,此时,传入参数是b,即双目运算时,后面一个参数是传入参数

有了对+的重载,编译器就将c=a+b理解为对运算符函数的调用,即c=operator+(a,b);

第 12 行,在 C++ 中,“类名(构造函数实参表)”这种写法表示生成一个临时对象。该临时对象没有名字,生存期就到包含它的语句执行完为止。因此,第 12 行实际上生成了一个临时的 Complex 对象作为 return 语句的返回值,该临时对象被初始化为 a、b 之和。第 16 行与第 12 行类似。

3. " =  "等号运算符的重载

"=" 运算符重载的  只能是类的成员函数

"=" 运算符重载的特殊性

赋值运算符“=”  要求左右两个操作数的类型是匹配的,或至少是兼容的,这是赋值运算符的现状。

赋值运算符“=”  重载的目的

有时希望=两边的操作数的类型即使不兼容也能够成立,这就需要对=进行重载。C++规定,=只能重载为成员函数。

4."()"运算符重载

"()" 运算符重载的  只能是类的成员函数

#include <iostream>  
  
class MyFunction {  
private:  
    int value;  
  
public:  
    MyFunction(int val=0) : value(0) {}  
  
    void operator()(int val) {  
        value = value + val;  
        std::cout << "New value: " << value << std::endl;  
    }  
};  
  
int main() {  
    MyFunction func(5);//执行构造函数  
  
    func(3);  //执行运算符重载函数  调用函数对象,将参数值传递给括号运算符  
  
    return 0;  
}
class cls
{
public:
    void operator() ()  //重载"()"操作符,"()"内无操作数
    {
        printf("HelloWorld!\n");
    }

    void operator() (const char* str) //重载"()","()"内的操作数是字符串
    {
        printf("%s", str);
    }
};


int main(void)
{
    cls cc;

    cc();//执行无参的括号运算符重载函数

    cc("Hello Linux\n");//执行有参的括号运算符重载函数

    return 0;
}

注意:区分对象的构造函数和括号运算符重载函数。构造函数只在定义对象时执行。

单一的对象加括号的形式,如  对象()  的结合体,一定是该对象里面的括号运算符重载函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值