
目录
前言
一、运算符重载的概念
问题讨论:
运算符重载的实现:
运算符重载举例:
运算符重载的限制:
二、运算符重载函数作为类成员函数
三、运算符重载函数作为友元函数
四、类型转换
前言 C++ 预定义了一组运算符 ,用来表示 对数据的运算 : + 、 - 、*、 / 、 % 、 << 、 >> 、 & 、 | 、 ~ 、 ^ 、 && 、 || 、!、 == 、 != 、 =…… 。 只能用于基本的数据类型 : 整型、实型、字符型、 逻辑型 、 …… 。 cin 和 cout 使用运算符 “ >>” 、 “ <<” 进行流 *** 作时,要求 *** 作数是 基本数据类型 。 C++ 提供了 数据抽象的手段 ,允许用户定义抽象数据类型: 类 通过 调用类的成员函数 ,对它的对象进行 *** 作。 但是,在有些时候, 用类的成员函数 来 *** 作对象时, 很不方便 。例如: 对一个群体,按照他们的 体重指数 进行排序:涉 及不同对象中的“体重指数”成员属性。 在数学上,两个复数可以直接进行 + 、 - 等运算。
但在C++中,直接将+或-用于复数是不允许的。
因此 我们希望: 对一些抽象数据类型 ,也能够 直接使用 C++ 提供的运算符 : 程序更简洁代码更容易理解
例如:
bool compareQuata = Bill < Jimmy
/*Bill和Jimmy是CMan的两个对象
比较他们的体重指数*/
complex_a + complex_b
/*complex_a和complex_b是两个复数对象
求两个复数的和*/
提示:以下是本篇文章正文内容,下面案例可供参考
int x , y
y = x + y ;
对于复数加法来说,有:
complex c1 , c2 ; // 复数类对象
c1 = c1.Cadd (c2 ) ; // 调用函数计算两个复数的和
对于矩阵加法来说,有:
matrix m1 , m2 ; // 矩阵类对象
m1 = m1.Madd ( m2 ) ;// 调用函数计算两个矩阵的和
能否表示为
c1 = c1 + c2 ;
m1 = m1+m2;
例子:
#include
using namespace std;
class CComplex {
private: double real, image;
public:
CComplex(double r = 0, double i = 0);
CComplex& addComplexToItself(const CComplex &r_c);
void print() const;
};
int main(){
CComplex a(3, 4), b(5, 6);
a = a.addComplexToItself(b);
//a += b; // error, 运算符’+=’没有被重载
a.print();
}
/
#include
using namespace std;
class CComplex {
private: double real, image;
public:
CComplex(double r = 0, double i = 0):real(r),image(i){cout<<"constructor"<0)
cout<<"+";
}
if(image){
if(abs(image)!=1)
cout<
问题讨论:
CComplex类定义了一个addComplexToItself()成员函数实现复数类对象的自增运算。
基本数据类型变量的自增可以用’+=’运算符实现。
能否直接对一个CComple类对象进行’+=’运算? 如a += b?
运算符重载的实现: 运算符重载 是通过 函数 实现的,运算符的重载即 函数的重载 。运算符重载函数的一般形式为: 返回类型 operator 运算符符号 ( 参数说明 ); 运算符重载举例:CComplex类定义一个运算符重载函数:
CComplex& operator +=
(const CComplex& r_c)
编译程序 将 复数类对象的运算表达式 转化为 对运算符重载成员函数的调用 , 运算的左 *** 作数对象 作为成员函数 调用的目标对象 , 右 *** 作数 转化为运算符 函数的实参 :例子:
#include
using namespace std;
class CComplex {
private: double real, image;
public:
CComplex(double r = 0, double i = 0):real(r),image(i){cout<<"constructor"<0) cout<<"+"; }
if(image){
if(abs(image)!=1)cout<
运算符重载的限制:
只能重载已经存在的C++运算符。
运算符重载不能改变运算符 *** 作数的个数、优先级和结合性。
运算符的 *** 作数 必须 至少有一个某个类的类对象 ,否则不能对运算符进行重载。 重载运算符 不可以使用缺省参数 。 除了 赋值运算符 = 外,重载运算符可由 派生类 继承下去。 二、运算符重载函数作为类成员函数 实现 运算符重载函数可以通过 2 种形式 实现: 类成员函数 友元函数 这两种方式非常相似, 关键区别 在于: 成员函数 具有 this 指针 友员函数 没有 this 指针 说明 :编译程序处理成员函数时,为它设置了一个this指针。
在 重载运算符函数 中, 默认 this 指针对应的缺省参数 就是其中之 一个参数 。 对于 一元运算符 函数使用的就是规定的 this 指针所指的参数(自身的参数)
对于 二元运算 符对应是二元运算的左 *** 作数。 运算符重载函数定义为其 *** 作数所属类的成员函数时, 参数的个数 要 比运算符的 *** 作数个数 少一个 。 重载 一元运算符 时,不再显式指明参数; 重载 二元运算符 时,只需显式指明一个参数;二元运算符以成员函数形式重载,左 *** 作数必须为类对象,目标对象作为左 *** 作数。
声明格式:成员运算符重载函数在类中的声明格式为:
class X
{ ……
<返回数据类型> operator <运算符> (<参数表>);
};
成员运算符重载函数在类外定义的格式为:
<返回数据类型> X::operator <运算符> (<参数表>)
{
<函数体>
}
程序:
#include
using namespace std;
class CComplex{
private:
double real, image;
public:
CComplex(double a=0.0, double b=0.0)
{ real = a; image = b; }
CComplex(const CComplex &r)
{ real = r.real; image = r.image; }
void print() const;
const CComplex& operator+= (const CComplex &r_c);
const CComplex& operator+= (double c);//实部、虚部加c
CComplex operator+ (const CComplex &r_c) const;
CComplex operator+ (double c) const;
};
void CComplex::print() const{
cout<<"real="<
三.读入数据
运算符重载函数可以用友元函数的形式来实现。
函数参数的个数 与 运算符的 *** 作数个数 相同 第一个参数 表示 左 *** 作数 第二个参数 表示 右 *** 作数 参数 中必须有一个类型为 类对象或类对象引用赋值运算符‘=’、下标运算符‘[ ]’、成员选择运算符‘->’和函数调用运算符‘()’、所有的类型转换运算符不能用友元函数形式重载。
声明格式:友元运算符重载函数在类中的声明格式为:
class X {
……
friend <返回数据类型> operator <运算符> (<参数表>);
};
友元运算符重载函数在类外定义的格式为:
<返回数据类型> operator <运算符> (<参数表>)
{
<函数体>
}
程序:
#include
using namespace std;
class CComplex{
private:
double real, image;
public:
CComplex(double a=0.0, double b=0.0)
{ real = a; image = b; }
CComplex(double c) { real = c; image = 0.0; }
void print() const;
friend void operator+= (CComplex &r_x, const CComplex &r_y);
friend CComplex operator+ (const CComplex &r_x, const CComplex &r_y);
};
void CComplex::print() const{
cout<<"real="<
一元运算符重载:
如同“++”运算符有前缀和后缀两种使用形式一样,“++”和“--”重载运算符也有前缀和后缀两种运算符重载形式,以“++”重载运算符为例,其语法格式如下:
<函数类型> operator ++(); //前缀运算
<函数类型> operator ++(int); //后缀运算
使用前缀运算符的语法格式如下:
++<对象>;
使用后缀运算符的语法格式如下:
<对象>++;
1.成员函数重载实例:
#include
using namespace std;
class Increase{
private:
int value;
public:
Increase(int x):value(x){}
void display(){cout <<"value =" <
运行结果:
value=20
value=20
value=21
value=22
value=24
2、友元函数重载示例:
#include
using namespace std;
class Increase{
private:
int value;
public:
Increase(int x):value(x){}
friend Increase & operator++(Increase &); //前增量
friend Increase operator++(Increase &,int); //后增量
void display(){ cout <<"value=" <
编程练习题:
编程实现一个日期类 Date ,包括年、月、日等私有数据成员。要求实现日期的基本运算,如一个日期加上天数、一个日期减去天数、两日期相差的天数等。#include
#include
using namespace std;
class Date{
int year,month,day;
int days[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
public:
Date(int y=0,int m=0,int d=0):year(y),month(m),day(d){}
void judge1(int y){
if(y%400==0 || (y%4==0 && y%100!=0))
days[2]=29;
else
days[2]=28;
}
long judge2(int y){
if(y%400==0 || (y%4==0 && y%100!=0))
return 366;
else
return 365;
}
Date operator+(int d){
Date t(*this);
d+=t.day;
judge1(t.year);
while(d>days[t.month]){
d-=days[t.month];
t.month++;
if(t.month==13){
t.month=1;
t.year++;
judge1(t.year);
}
}
t.day=d;
return t;
}
Date operator-(int d){
Date t(*this);
d=t.day-d;
judge1(t.year);
while(d<=0){
t.month--;
if(t.month==0){
t.month=12;
t.year--;
judge1(t.year);
}
d+=days[t.month];
}
t.day=d;
return t;
}
long operator-(const Date& date){
int startyear=year
四、类型转换
类型转换
是将
一种类型的值
转换为
另一种类型的值
。
对于
类
类型
,是否也存在一种类型转换机制,使得
类对象之间
能进行类型转换
?
在
C++
语言中,
类
被视为
用户定义的类型
,可以像系统预定义类型一样进行类型转换。
C++
语言允许的类型转换:
C++ 语言允许的类型转换有 4 种 : 标准 类型 -> 标准 类型 标准 类型 -> 类 类型 类 类型 -> 标准 类型 类 类型 -> 类 类型
标准类型是除class、struct和union类型外的其他所有类型。
对于标准类型, C++ 语言提供了 两种 类型转换 : 隐式 类型转换 显式 类型转换欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)