C++ 运算符重载

目录

1. 运算符重载

1.1 概念

1.2 友元函数运算符重载

1.3 成员函数运算符重载

1.4 赋值运算符重载

1.5 类型转换运算符重载

1.6 注意事项


1. 运算符重载

1.1 概念

C++中可以把部分运算符看做成函数,此时运算符也可以重载。

运算符预定义的操作只能针对基本数据类型,但是对于自定义类型,也需要类似的运算操作,此时就可以重新定义这些运算符的功能,使其支持特定类型,完成特定的操作。

如果不做特殊处理,C++ 的 +、-、*、/ 等运算符只能用于对基本类型的常量或变量进行运算,不能用于对象之间的运算。类的对象中有很多个成员变量,运算符不知道对哪个成员变量进行运算,这时候就需要对运算符进行重载,让运算符明确知道要对哪个成员变量进行运算。

其实相当于定义一个函数来进行特定的运算。

运算符重载有两种实现方式:

        ● 友元函数运算符重载

        ● 成员函数运算符重载

1.2 友元函数运算符重载

(1)在类内声明实现运算符重载功能的友元函数名称

(2)在类外定义函数体定义函数实现运算符重载功能

 友元函数实现运算符重载实例:

注意:当自增运算符进行重载时,前置自增 ++i 与后置自增i++的函数名字一样,但是参数不一样,通过函数重载进行区分。

如果是 前置自增 ++i , 参数只有一个进行自增的变量。

如果是后置自增 i++,参数除了进行自增的变量,还需要加一个哑元参数。

// 友元函数 ++运算符重载声明
    // 利用参数不同,进行函数重载
    friend Myint operator ++(Myint &i);   // 前置++
    friend Myint operator ++(Myint &i,int);   // 后置++

#include <iostream>

using namespace std;

class Myint
{
private:
    int a;

public:
    Myint(int a):a(a){}

    int get_int()
    {
        return a;
    }

    // 友元函数 +运算符重载声明
    friend Myint operator +(Myint &a,Myint &b);
    // 友元函数 -运算符重载声明
    friend Myint operator -(Myint &a,Myint &b);

    // 友元函数 ++运算符重载声明
    // 利用参数不同,进行函数重载
    friend Myint operator ++(Myint &i);   // 前置++
    friend Myint operator ++(Myint &i,int);   // 后置++
};

//加法重载
Myint operator +(Myint &i,Myint &j)
{
    //    Myint int4(0);
    //    int4.a = i.a + j.a;
    //    return int4;

    return i.a + j.a;
}

//减法重载
Myint operator -(Myint &i,Myint &j)
{
    Myint int4(0);
    int4.a = i.a - j.a;
    return int4;
}

// 前置++
Myint operator ++(Myint &i)
{
    //    Myint int4(0);
    //    ++int4.a
    //    return int4;

    return ++i.a;
}

// 后置++
Myint operator ++(Myint &i,int)
{
//        Myint int4(0);
//        int4.a = i.a++;
//        return int4;

            return i.a++;
}

int main()
{
    Myint int1(2);
    Myint int2(int1);  // 拷贝构造函数
    cout << int2.get_int() << endl;
    cout << endl;

    cout << "加法重载:" << endl;
    Myint int3 = int1 + int2;
    cout << int3.get_int() << endl;
    cout << endl;

    cout << "减法重载:" << endl;
    Myint int5 = int1 - int2;
    cout << int5.get_int() << endl;
    cout << endl;

    cout << "后置自增:" << endl;
    cout << (int3++).get_int() << endl; // 后置自增
    cout << int3.get_int() << endl;
    cout << endl;
    Myint int6 = int3++;
    cout << int6.get_int() << endl;
    cout << endl;

    cout << "前置自增:" << endl;
    cout << (++int3).get_int() << endl; // 前置自增
    cout << int3.get_int() << endl;
    cout << endl;
    Myint int7 = ++int3;
    cout << int7.get_int() << endl;
    
    return 0;
}

1.3 成员函数运算符重载

成员函数运算符重载相比于友元函数重载,最主要的区别是,友元函数的第一个输入参数,在成员函数运算符重载使用this指针代替,因此同样的运算符重载,成员函数运算符重载比友元函数运算符重载参数少一个。

 成员函数进行运算符重载实例:

因为进行自增的变量已经进行由this指针代替,所以前置自增为无参函数,后置自增只需要写哑元参数即可。

// 成员函数 ++运算符重载声明
    Myint operator ++();   // 前置++
    Myint operator ++(int);   // 后置++

#include <iostream>

using namespace std;

class Myint
{
private:
    int a;

public:
    Myint(int a):a(a){}

    int get_int()
    {
        return a;
    }

    // 成员函数 +运算符重载声明
    Myint operator +(Myint &i);
    // 成员函数 -运算符重载声明
    Myint operator -(Myint &i);

    // 成员函数 ++运算符重载声明
    Myint operator ++();   // 前置++
    Myint operator ++(int);   // 后置++
};

//加法重载
Myint Myint::operator +(Myint &i)
{
    return this->a + i.a;
}

//减法重载
Myint Myint::operator -(Myint &i)
{
    return this->a - i.a;
}

// 前置++
Myint Myint::operator ++()
{


    return ++this->a;
}

// 后置++
Myint Myint::operator ++(int)
{
    return this->a++;
}

int main()
{
    Myint int1(2);
    Myint int2(int1);  // 拷贝构造函数
    cout << int2.get_int() << endl;
    cout << endl;

    cout << "加法重载:" << endl;
    Myint int3 = int1 + int2;
    cout << int3.get_int() << endl;
    cout << endl;

    cout << "减法重载:" << endl;
    Myint int5 = int1 - int2;
    cout << int5.get_int() << endl;
    cout << endl;

    cout << "后置自增:" << endl;
    cout << (int3++).get_int() << endl; // 后置自增
    cout << int3.get_int() << endl;
    cout << endl;
    Myint int6 = int3++;
    cout << int6.get_int() << endl;
    cout << endl;


    cout << "前置自增:" << endl;
    cout << (++int3).get_int() << endl; // 前置自增
    cout << int3.get_int() << endl;
    cout << endl;
    Myint int7 = ++int3;
    cout << int7.get_int() << endl;

    return 0;
}

1.4 赋值运算符重载

除了之前学习的无参构造函数、拷贝构造函数和析构函数以外,如果程序员不手写,编译还会给一个类添加赋值运算符重载函数。

赋值运算符=要求左右两个操作数的类型是匹配的,或至少是兼容的。有时希望=两边的操作数的类型即使不兼容也能够成立,这就需要对=进行重载。

C++规定,=赋值运算符重载只能使用成员函数运算符重载。

 赋值运算符重载实例:

int2 = int1; 当进行这句赋值操作时,就需要利用赋值运算符重载。

#include <iostream>

using namespace std;

class MyInt
{
private:
    int a;
public:
    MyInt(int a):a(a){}

    int get_int()
    {
        return a;
    }

    MyInt& operator=(MyInt &i)
    {
        // 编译器自动添加的运算符重载不会打印这句话
        cout << "赋值运算符重载被调用了" << endl;
        this->a = i.a;
        return *this;
    }

};

int main()
{
    cout << "Hello World!" << endl;
    MyInt int1(2);
    MyInt int2(4);

    cout << int1.get_int() << endl;
    cout << int2.get_int() << endl;
    cout << endl;

    int2 = int1;
    cout << int1.get_int() << endl;
    cout << int2.get_int() << endl;

    return 0;
}

1.5 类型转换运算符重载

C++ 中,类型的名字(包括类的名字)本身也是一种运算符,即类型强制转换运算符。

类型强制转换运算符是单目运算符,也可以被重载,但只能重载为成员函数,不能重载为全局函数。

经过适当重载后,(类型名)对象这个对对象进行强制类型转换的表达式就等价于对象.operator 类型名(),即变成对运算符函数的调用。

必须使用成员函数运算符重载,并且格式比较特殊。

类型转换运算符重载实例:

int a= int1;  运行这一句的时候,把对象中的int类型的成员函数给 变量 int a

string b = int1; 运行这一句的时候,把对象中的srtring类型的成员变量 给 strng b

#include <iostream>

using namespace std;

class MyInt
{
private:
    int a;
    string str = "hello";

public:
    MyInt(int a,string b):a(a),str(b){}

    int get_int()
    {
        return a;
    }

    operator int()
    {
        return a;
    }

    operator string()
    {
        return str;
    }

};

int main()
{
    cout << "Hello World!" << endl;
    MyInt int1(2,"world");
    int a= int1;
    cout << "a=" << a << endl;
    cout << endl;

    string b = int1;
    cout << "b=" << b << endl;
    cout << endl;

    return 0;
}

1.6 注意事项

● 重载的运算符限制在C++语言中已有的运算符范围,不能创建新的运算符。

● 运算符重载本质上也是函数重载,但是不支持函数参数默认值。

● 重载之后的运算符不能改变运算符的优先级和结合性,也不能改变运算符的操作数和语法结构。

● 运算符重载必须基于或者包含自定义类型,即不能改变基本数据类型的运算规则。

● 重载的功能应该与原有的功能相似,避免没有目的的滥用运算符重载。

● 一般情况下,双目运算符建议使用友元函数运算符重载,单目运算符建议使用成员函数运算符重载。

  • 32
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值