您的位置:首页 > 编程语言 > C语言/C++

C++ 重载和类型转换函数

2018-03-08 12:55 267 查看
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型数据处理。

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

overload operator+(const overload &o){
return overload(num + o.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;
}


参考文章:类型转换函数
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: