C++ 运算符重载和类型转换函数

C++中对于用户自定义类对象的运算,要进行重载操作。如

class overload{
public:
    ...
private:
    int num;
};
overload o1, o2;
int num;
//要实现的加法操作如下:
/*1*/overload o3 = o1 + o2;
/*2*/overload o4 = o1 + (任意int型);
/*3*/overload o5 = (任意int型) + o2;
/*4*/num = (任意int型) + o2;
/*5*/num = o1 + o2;
//以及一些其他的组合,原理一致,此处不列出

首先要为类定义构造函数:

overload():num(0) {}
overload(int a):num(a) {}

对于1、2式,直接进行运算符的重载就行。系统会将o1+o2变为o1.operator+(o2)的形式。为了保持类的封装性,最好是重载为成员函数。

//此重载可以兼容1、2式
//对于2式中的int型整数,会通过一个隐式转换(构造函数中的overload(int a):num(a) {}),变为overload类型的对象,然后执行加操作
overload operator+(const overload &o){
    return overload(num + o.num); 
}
//上式多一步隐式转换,性能就会受到影响,所以可以采用专门的重载函数
overload operator+(const int x){
    return overload(num + x); 
}

PS:上述两个重载返回值写的都是构造函数类型,原因在于如果写的是以下结构

overload res(num + x);
return res; 

将会多出一个隐式的构造和析构过程(局部变量的拷贝引起),而直接返回构造函数,可以使此步骤发生在要赋值的类对象的内存空间中,减少构造和析构的过程。这叫做返回值优化(return value optimization)


对于3式,由于无法产生a.operator+(overator &)的类型,所以需要重载为友元函数,但是影响了一定的封装性(因为类要求private的成员不可被外部访问,只可以被内部访问,而友元函数不属于内部的函数)。

//友元函数
//第一个友元函数多一步隐式转换,第二、三不会有隐式转换,原理一致,写哪个都可以
friend overload operator+(const overload &o1, const overload &o2){
    return overload(o1.num + o2.num);
}
friend overload operator+(const int a, const overload &o2){
    return overload(o1.num + a);
}
friend overload operator+(const overload &o1, const int a){
    return overload(o1.num + a);
}

但是如果这还不能满足我们呢?如果我们要求类也可以转换为int型的数据呢?(4,5式)
这就要用到类型转换函数了。
类型转换函数形式如下:

operator 类型名( )
{
    实现转换的语句;
}

在函数名前面不能指定函数类型,函数没有参数。其返回值的类型是由函数名中指定的类型名来确定的。类型转换函数只能作为成员函数,因为转换的主体是本类的对象。不能作为友元函数或普通函数。
从函数形式可以看到,它与运算符重载函数相似,都是用关键字operator开头,只是被重载的是类型名。int类型经过重载后,除了原有的含义外,还获得新的含义(将一个overload类对象转换为int类型数据,并指定了转换方法)。这样,编译系统不仅能识别原有的int型数据,而且还会把overload类对象作为int型数据处理。

本例的类型转换函数如下:

operator int(){
    return num;
}

这个类型转换函数可以直接代替上述重载函数的功能,实现1,2,3,4,5式。

//o1,o2都转换为int类型的数据,进行相加后,再通过隐式转换,构造o3
overload o3 = o1 + o2;
overload o4 = o1 + (任意int型);
//没有int+overload类型的加法,但是系统会自动将o2变为int类型,执行加法后再构造o5
overload o5 = (任意int型) + o2;
num = (任意int型) + o2;
//o1,o2的结果转换为int
num = o1 + o2;

类型转换运算符的功能:当需要的时候,编译系统会自动调用这些函数,建立一个无名的临时对象(或临时变量)。

但是当类中同时出现以上函数时,会出现二义性,程序无法判定使用哪一种转换方法,所以需要自行选择合适的方法。
实验部分代码如下:

#include <iostream>
using namespace std;

class overload
{
public:
    overload():num(0) {}
    overload(int a):num(a) {}
#if 1
    overload operator+(const overload &o){
        return overload(num + o.num); 
    }
#endif

#if 0
    //类型转换函数
    operator int(){return num;}
#endif
    //友元函数
    friend ostream &operator<<(ostream &out, const overload &o){
        return out << o.num;
    }
#if 1
    friend overload operator+(const overload &o1, const overload &o2){
        return overload(o1.num + o2.num);
    }
#endif

private:
    int num;

};



int main()
{
    overload o1(3);
    overload o2(4);
    overload o3 = o1 + o2;
    cout << o3 << endl;
    overload o4 = o1 + 5;
    cout << o4 << endl;
    overload o5 = 6 + o1;
    cout << o5 << endl;
    //int n1 = o1 + o2;
    //cout << n1 << endl;

    return 0;
}

参考文章:类型转换函数

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值