C++ 重载和类型转换函数
2018-03-08 12:55
267 查看
C++中对于用户自定义类对象的运算,要进行重载操作。如
首先要为类定义构造函数:
对于1、2式,直接进行运算符的重载就行。系统会将o1+o2变为o1.operator+(o2)的形式。为了保持类的封装性,最好是重载为成员函数。
PS:上述两个重载返回值写的都是构造函数类型,原因在于如果写的是以下结构
将会多出一个隐式的构造和析构过程(局部变量的拷贝引起),而直接返回构造函数,可以使此步骤发生在要赋值的类对象的内存空间中,减少构造和析构的过程。这叫做返回值优化(return value optimization)。
对于3式,由于无法产生a.operator+(overator &)的类型,所以需要重载为友元函数,但是影响了一定的封装性(因为类要求private的成员不可被外部访问,只可以被内部访问,而友元函数不属于内部的函数)。
但是如果这还不能满足我们呢?如果我们要求类也可以转换为int型的数据呢?(4,5式)
这就要用到类型转换函数了。
类型转换函数形式如下:
在函数名前面不能指定函数类型,函数没有参数。其返回值的类型是由函数名中指定的类型名来确定的。类型转换函数只能作为成员函数,因为转换的主体是本类的对象。不能作为友元函数或普通函数。
从函数形式可以看到,它与运算符重载函数相似,都是用关键字operator开头,只是被重载的是类型名。int类型经过重载后,除了原有的含义外,还获得新的含义(将一个overload类对象转换为int类型数据,并指定了转换方法)。这样,编译系统不仅能识别原有的int型数据,而且还会把overload类对象作为int型数据处理。
本例的类型转换函数如下:
这个类型转换函数可以直接代替上述重载函数的功能,实现1,2,3,4,5式。
类型转换运算符的功能:当需要的时候,编译系统会自动调用这些函数,建立一个无名的临时对象(或临时变量)。
但是当类中同时出现以上函数时,会出现二义性,程序无法判定使用哪一种转换方法,所以需要自行选择合适的方法。
实验部分代码如下:
参考文章:类型转换函数
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;
}
参考文章:类型转换函数
相关文章推荐
- C++学习-函数重载和默认参数
- C++的函数重载原理分析
- C++之函数重载
- C++本质:类的赋值运算符=的重载,以及深拷贝和浅拷贝(转载)
- c++ 对象坐标相加重载
- C++重载(关于const的重载)
- 【C++面向对象】输入输出操作符的重载
- c++ 重载 new delete 用堆来分配内存
- JNI jstring与c++字符串类型转换函数
- C++模板编程->分辨重载优先级
- c++中不能重载的运算符
- C++中不可重载5个运算符
- 转载:c++重载、覆盖、隐藏——理不清的区别
- C++重载 隐藏和覆盖
- c++中 模板与重载入门代码
- (转自)C++覆盖、重载和隐藏的区别
- C++ 重载
- C++ 重载、重写、重定义
- c++(重载、覆盖、隐藏)
- C++函数重定义、重载、重写