Guangxi University of Science and Technology
实验报告
实验课程: C++程序设计教程
实验内容:运算符重载
院(系):
专业:软件工程方向
班级:
学生姓名:
学号:
指导教师:
2013年 11 月 18日
一.实验目的:
(1)掌握运算符重载的概念和应用。
(2)掌握用成员函数、友元函数重载运算符的特点。
(3)理解一些特殊运算符的重载。
二.实验内容
(-)实验题目一:
(1)将以下程序更改为友元函数重载的形式并上机运行。
#include
class RMB{ //人民币类
public:
RMB(double d){ yuan=d; jf=(d-yuan)/100; }
RMB interest(double rate); //计算利息
RMB add(RMB d); //人民币加
void display(){ cout <<(yuan + jf / 100.0) << endl; }
RMB operator+(RMB d){ return RMB(yuan+d.yuan+(jf+d.jf)/100); } //人民币加的运算符重载 RMB operator*(double rate){ return RMB((yuan+jf/100)*rate);} private:
unsigned int yuan; //元
unsigned int jf; //角分
};
RMB RMB::interest(double rate)
{
return RMB((yuan + jf / 100.0) * rate);
}
RMB RMB::add(RMB d)
{
return RMB(yuan + d.yuan + jf / 100.0 + d.jf / 100.0);
} //以下是计算应付人民币的两个版本
RMB expense1(RMB principle, double rate)
{
RMB interest = principle.interest(rate);
return principle.add(interest);
}
RMB expense2(RMB principle, double rate)
{
RMB interest = principle * rate; //本金乘利息
return principle + interest; //连本带利
void main()
{
RMB x = 10000.0;
double yrate = 0.035;
expense1(x,yrate).display();
expense2(x,yrate).display();
}
1.要点分析:
2.程序源代码:
#include
class RMB{ //人民币类
public:
RMB(double d){ yuan=d; jf=(d-yuan)/100; }
RMB interest(double rate); //计算利息
RMB add(RMB d); //人民币加
void display(){ cout <<(yuan + jf / 100.0) << endl; }
RMB operator+(RMB d){ return RMB(yuan+d.yuan+(jf+d.jf)/100); } //人民币加的运算符重载 RMB operator*(double rate){ return RMB((yuan+jf/100)*rate);} private:
unsigned int yuan; //元
unsigned int jf; //角分
};
RMB RMB::interest(double rate)
{
return RMB((yuan + jf / 100.0) * rate);
}
RMB RMB::add(RMB d)
{
return RMB(yuan + d.yuan + jf / 100.0 + d.jf / 100.0);
} //以下是计算应付人民币的两个版本
RMB expense1(RMB principle, double rate)
{
RMB interest = principle.interest(rate);
return principle.add(interest);
}
RMB expense2(RMB principle, double rate)
{
RMB interest = principle * rate; //本金乘利息
return principle + interest; //连本带利
void main()
{
RMB x = 10000.0;
double yrate = 0.035;
expense1(x,yrate).display();
expense2(x,yrate).display();
}
3.实验结果:
(二)实验题目二:
(2)将以下程序中重载运算符定义函数的返回类型更改(值返回更改为引用返回,引用返回更改为值返回),观察程序运行结果,说明原因。
#include
class RMB{
public:
RMB(unsigned int d, unsigned int c);
friend RMB operator +(RMB&, RMB&);
friend RMB& operator ++(RMB&);
void display(){ cout <<(yuan + jf / 100.0) << endl; }
protected:
unsigned int yuan;
unsigned int jf;
};
RMB::RMB(unsigned int d, unsigned int c)
{
yuan = d;
jf = c;
while ( jf >=100 ){ //以使构造时,确保角分值小于100
yuan ++;
jf -= 100;
}
}
RMB operator+(RMB& s1, RMB& s2) // 此处改为RMB& operator+(RMB& s1, RMB& s2)
{
unsigned int jf = s1.jf + s2.jf;
unsigned int yuan = s1.yuan + s2.yuan;
RMB result( yuan, jf );
return result;
}
RMB& operator ++(RMB& s) //此处改为RMB operator ++(RMB& s)
s.jf ++;
if(s.jf >= 100){
s.jf -= 100;
s.yuan++;
}
return s;
}
void main()
{
RMB d1(1, 60);
RMB d2(2, 50);
RMB d3(0, 0);
d3 = d1 + d2;
++d3;
d3.display();
}
1.要点分析:
2.程序源代码:
3.实验结果
(三)实验题目三:
(3)上机分析下面程序,掌握运算符重载的方法。
#include
class Complex
{
friend Complex operator+( const double &d, const Complex &c );
friend Complex operator-( const double &d, const Complex &c );
double m_fReal, m_fImag;
public:
Complex( const double &r = 0, const double &i = 0): m_fReal( r ), m_fImag( i ) {}
Complex( const Complex &c ): m_fReal( c.m_fReal ), m_fImag( c.m_fImag )
{}
double GetReal() const
{
return m_fReal;
}
double GetImag() const
return m_fImag;
}
Complex& operator=( const Complex &c )
{
if( this == &c )
{
return *this;
}
m_fReal=c.m_fReal;
m_fImag=c.m_fImag;
return *this;
}
Complex operator+( const Complex &c )
{
return Complex( m_fReal+c.m_fReal, m_fImag+c.m_fImag ); }
Complex operator-( const Complex &c )
{
return Complex( m_fReal-c.m_fReal, m_fImag-c.m_fImag ); }
Complex operator+( const double &d )
{
return Complex( m_fReal+d, m_fImag );
}
Complex operator-( const double &d )
{
return Complex( m_fReal-d, m_fImag );
}
};
Complex operator+( const double &d, const Complex &c ) {
return Complex( d + c.m_fReal, c.m_fImag );
}
Complex operator-( const double &d, const Complex &c ) {
return Complex( d - c.m_fReal, c.m_fImag );
}
int main()
{
Complex c1( 3.3, 4.4 );
Complex c2( 5.5, 2.2 );
Complex c3;
c3 = c1 + c2;
cout << "C3 = " << c3.GetReal() << "+i" << c3.GetImag() << endl;
c3 = c1 - c2;
cout << "C3 = " << c3.GetReal() << "+i" << c3.GetImag() << endl;
c3 = c1 + c2;
cout << "C3 = " << c3.GetReal() << "+i" << c3.GetImag() << endl;
c3 = c1 + 1.1;
cout << "C3 = " << c3.GetReal() << "+i" << c3.GetImag() << endl;
c3 = c1 - 1.1;
cout << "C3 = " << c3.GetReal() << "+i" << c3.GetImag() << endl;
c3 = 9.9 + c1;
cout << "C3 = " << c3.GetReal() << "+i" << c3.GetImag() << endl;
c3 = 9.9 - c1;
cout << "C3 = " << c3.GetReal() << "+i" << c3.GetImag() << endl;
( c3 = c1 ) = c2;
cout << "C3 = " << c3.GetReal() << "+i" << c3.GetImag() << endl;
return 0;
}
注意重载“=”运算符的方法:首先应判断是否是自身赋值,其次应注意返回值是引用,这是为了支持( c3 = c1 ) = c2这种用法。
1.要点分析:
2.程序源代码:
3.实验结果
(四)实验题目四:
完善下列程序,利用运算符重载的形式使之能够实现矩阵类Matrix 的加减乘 (+-*)及赋值(=)运算。
//头文件MatrixException.h
#include
#include
using namespace std;
class MatrixException : public logic_error
{
public:
MatrixException(const string& s) : logic_error(s)
{}
};
class Singular: public MatrixException
{
public:
Singular(const string& s) : MatrixException("Singular: "+s)
{}
};
class InvalidIndex: public MatrixException
{
public:
InvalidIndex(const string& s) : MatrixException("Invalid index: "+s)
{}
};
class IncompatibleDimension: public MatrixException
{
public:
IncompatibleDimension(const string& s) : MatrixException("Incompatible Dimensions: "+s)
{}
};
//头文件Matrix.h
#include "MatrixException.h"
class Matrix
{
double* elems; // 存放矩阵中各元素,按行存放
int row, col; // 矩阵的行与列
protected:
double rowTimesCol(int i, const Matrix &b, int j ) const; /矩阵的第i行矩阵b 的第j列相乘
public:
Matrix(int r, int c);
Matrix(double* m, int r, int c);
Matrix( const Matrix &m );
~Matrix();
//重载运算符" =",实现矩阵赋值,若进行运算的矩阵维数不同,抛出IncompatibleDimension异常
Matrix& operator =(const Matrix& b) throw(IncompatibleDimension);
//重载运算符"( )",用来返回某一个矩阵元素值,若所取矩阵下标非法,抛出InvalidIndex 异常
double& operator () (int i, int j) throw(InvalidIndex);
const double& operator () (int i, int j) const throw(InvalidIndex);
//给矩阵元素赋值,若所设置矩阵元素下标非法,抛出InvalidIndex 异常
void SetElem(int i, int j, double val) throw(InvalidIndex);
//重载运算符"*",实现矩阵相乘,
//若前一个矩阵的列数不等于后一个矩阵的行数,抛出IncompatibleDimension异常
Matrix operator *(const Matrix& b) const throw(IncompatibleDimension);
//重载运算符" +",实现矩阵相加,若进行运算的矩阵维数不同,抛出IncompatibleDimension 异常
Matrix operator +(const Matrix& b) const throw(IncompatibleDimension); //重载运算符" -",实现矩阵相减//若进行运算的矩阵维数不同,抛出IncompatibleDimension异常
Matrix operator -(const Matrix& b) const throw(IncompatibleDimension); void Print() const; //按行显示输出矩阵中各元素
};
//成员函数的定义文件Matrix.cpp
#include
#include
#include
#include "Matrix.h"
using namespace std;
string int2String(int i) //将整型数转换为String类型
{
char buf[64];
ostrstream mystr(buf, 64);
mystr << i << '\0';
return string(buf);
}
Matrix::Matrix(int r, int c)
{
if ( r > 0 && c > 0 )
{ row = r; col = c;
elems = new double[r * c]; //为矩阵动态分配存储
}
else
{
elems = NULL;
row=col=0;
}
}
Matrix::Matrix( double* m, int r, int c )
{
if ( r > 0 && c > 0 )
{
row = r; col = c;
elems = new double[r * c];
}
else
{
elems = NULL;
row=col=0;
}
if ( elems != NULL )
{
for (int i=0; i < r*c; i++)
{
elems[i] = m[i];
}
}
}
Matrix::Matrix( const Matrix &m ) : row( m.row ), col( m.col ) {
if ( NULL == m.elems )
{
elems = NULL;
}
else
{
int total = row*col;
elems = new double[total];
for( int i = 0; i < total; ++i )
{
elems[i] = m.elems[i];
}
}
}
Matrix::~Matrix()
{
delete []elems; //释放矩阵所占的存储
}
Matrix& Matrix::operator =(const Matrix& b) throw(IncompatibleDimension) {
//…
}
//重载运算符"( )"可以由给出的矩阵行列得到相应的矩阵元素值
//之所以重载"( )"而不是"[]",是因为避免数组elems所造成的二义性
double& Matrix::operator () (int r, int c) throw(InvalidIndex)
{
if ( r<0 || r>=row || c<0 || c>=col )
{
throw( InvalidIndex(string("Get Element(")
+ int2String(r) + "," + int2String(c) + ")"
+ " from (" + int2String(row) + " x "
+ int2String(col) + ")" + " matrix." ) );
}
return elems[r*col+c];
}
const double& Matrix::operator () (int r, int c) const throw(InvalidIndex) {
if ( r<0 || r>=row || c<0 || c>=col )
{
throw( InvalidIndex(string("Get Element(")
+ int2String(r) + "," + int2String(c) + ")"
+ " from (" + int2String(row) + " x "
+ int2String(col) + ")" + " matrix." ) );
}
return elems[r*col+c];
}
void Matrix::SetElem(int r, int c, double val) throw(InvalidIndex)
{
if ( r<0 || r>=row || c<0 || c>=col )
{
throw(InvalidIndex(string("Set Element(")
+ int2String(r) + "," + int2String(c) + ")"
+ " for (" + int2String(row) + " x "
+ int2String(col) + ")" + " matrix." ) );
}
elems[r*col+c] = val;
}
Matrix Matrix::operator*(const Matrix& b) const throw(IncompatibleDimension)
{
//…
}
Matrix Matrix::operator +(const Matrix& b) const throw(IncompatibleDimension) {
//…
}
Matrix Matrix::operator -(const Matrix& b) const throw(IncompatibleDimension)
{
//…
}
void Matrix::Print() const
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col-1; j++)
{
cout << elems[i*col+j] << "\t";
}
cout << elems[i*col+col-1];
cout< } cout< } double Matrix::rowTimesCol( int i, const Matrix &b, int j ) const { double sum=0.0; for (int k = 0; k < col; k++) sum += elems[i*col+k] * b.elems[k*b.col+j]; return sum; } //测试文件MatrixMain.cpp #include #include "Matrix.h" using namespace std; int main() { try { //创建矩阵对象 double a[20]= {1.0, 3.0, -2.0, 0.0, 4.0, -2.0, -1.0, 5.0, -7.0, 2.0, 0.0, 8.0, 4.0, 1.0, -5.0, 3.0, -3.0, 2.0, -4.0, 1.0}; double b[15]= {4.0, 5.0, -1.0, 2.0, -2.0, 6.0, 7.0, 8.0, 1.0, 0.0, 3.0, -5.0, 9.0, 8.0, -6.0}; Matrix x1(a, 4, 5); cout<<"the matrix of x1 is:"< x1.Print(); Matrix y1(b, 5, 3); cout<<"the matrix of y1 is:"< y1.Print(); Matrix z1 = x1*y1; //两个矩阵相乘 cout<<"the matrix of z1=x1*y1 is:"< z1.Print(); Matrix x2(2, 2); x2.SetElem(0, 0, 1.0); //为矩阵对象添加元素 x2.SetElem(0, 1, 2.0); x2.SetElem(1, 0, 3.0); x2.SetElem(1, 1, 4.0); cout<<"the matrix of x2 is:"< x2.Print(); cout<<"x1*x2 is:"< x1*x2; //两个维数不匹配矩阵相乘,产生异常cout<<"x1-x2 is:"< x1-x2; //两个维数不匹配矩阵相减,产生异常 cout<<"Set a new element for x1:"< x1.SetElem (7, 8, 30); //设置矩阵元素超界,产生异常 cout<<"Get a element from x1:"< x1(4, 5); // 取不存在的矩阵元素,产生异常 } catch(MatrixException& e) { cout << e.what() << endl; //获取异常信息 } return 0; } 1.要点分析: 2,程序源代码: 3.实验结果: 三.个人小结 通过此次实验,我掌握了模板概念,了解异常处理机制,并对C++编程有了更进一步的理解! 实验十三 1.实验目的 通过本次实验 (1)理解友元函数与运算符重载函数的概念; (2)学会友元函数的定义与使用方法; (3)掌握运算符重载函数的定义与使用方法; 2.实验要求 (1)编写实验程序 (2)在VC++运行环境中,输入源程序 (3)编译运行源程序 (4)输入测试数据进行程序测试; (5)写出运行结果。 3.实验内容 (1)定义一个复数类,重载“-=”运算符,使这个运算符能直接完成复数的“-=”运算。分别用成员函数与友元函数编写运算符重载函数。在主函数中定义复数对象c1(10,20)、c2(15,30),进行c2-=c1的复数运算,并输出c1、c2的复数值。 参考资料: (1)成员函数 # include 运算符重载 一.单项选择题 1.下列运算符中,运算符在C++中不能重载。 A.?: B.+ C. D.<= 解:C++中不能被重载的运算符有:·,一,::,?:。本题答案为A。 2.下列运算符中,运算符在C++中不能重载。 A.&& B.[] C.:: D.new 解:c++中不能被重载的运算符有:·,·+,::,?:。本题答案为c。 3.下列关于运算符重载的描述中,是正确的。 A.运算符重载可以改变操作数的个数 B.运算符重载可以改变优先级 C.运算符重载可以改变结合性 D.运算符重载不可以改变语法结构 解:运算符重载不能改变操作数的个数、运算符的优先级、运算符的结合性和运算程的语法结构。本题答案为D。 4.友元运算符objl>obj2被C++编译器解释为。 A.operator>(objl,obj2) B.>(obj1,obj2) C.obj2.operator:>(obj1) D.objl.operator>(obj2) 解:重载为友元函数的运算符的调用形式如下: operator<运算符>(<参数1>,<参数2>) 等价于:<参数1><运算符><参数2> 本题答案为A。 5.现需要对list类对象使用的逻辑运算符“==”重载,以下函数声明是正确的。 A、list & list::operator==(const list &a); B、list list::operator==(const list &a); C、bool & list::operator==(const list &a); D、bool list::operator==(const list &a); 6. 以下类中分别说明了“+=”和“++”运算符重载函数的原型。如果主函数中有定义: fun m,c,d;,那么,执行语句c=m++; 时,编译器把m++解释为: (33) A) c.operator++(m); B) m=operator++(m); C) m.operator++(m); D) operator++(m); class fun { public: .. .. .. fun operator +=(fun ); friend fun operator ++(fun &,int); }; 答案:D 7. 在第33题中,当执行语句d+=m; 时,C++编译器对语句作如下解释: (34) A. d=operator+=(m); B. m=operator+=(d); C. d.operator+=(m); D. m.operator+=(d); 答案:C 8. 设有以下类定义,其中说明了“+”运算符重载函数的原型。这是一个友元函数,当类 实验五运算符重载 【实验目的】 1.进一步了解运算符重载的概念和使用方法。 2.掌握几种常用的运算符重载的方法。 3.了解转换构造函数的使用方法。 4.了解在Visual C++6.0环境下进行运算符重载要注意的问题. 【实验要求】 1.硬件基本配置:Intel PentiumIII以上级别的CPU,大于64MB的内存。 2.软件要求:Window 2000操作系统,Visual Studio 6.0或更高版本开发环境。 3.实验学时:2学时 4.实现实验内容中的题目。 5.写实验报告 【实验内容】 (1)声明一个复数类Complex,重载运算符“+’’,“一”,“*”,“/”使之能用于复数的加、减、乘、除.运算符重载函数作为Complex类的成员函数,重载流提取运算符实现对复数的输出。编程序,分别求两个复数之和、差、积和商并用重载后的流运算符进行输出。 请思考:你编的程序能否用于一个整数与一个复数的算术运算?如4+ (5-2i). (2)声明一个复数类Complex,重载运算符“+“,使之能用于复数的加法运算。 参加运算的两个运算量可以都是类对象.也可以其中有一个是整数,顺序任意。例如, cl+c2, i+cl,cl+i均合法(设i为整数,c1, c2为复数)。 运行程序.分别求两个复数之和、整数和复数之和。 (3)有两个矩阵a和b,均为2行3列。求两个矩阵之和。重载运算符“+”,使之能用于矩阵相加。如c=a+b。重载流提取运算符实现对矩阵的输出如:cout< 运算符重载复习题 1. 重载赋值操作符时,应声明为( ) A. 友元函数 B. 虚函数 C. 成员函数 D. 多态函数 2.关于重载的描述,正确的是( ) A.函数重载只能在成员函数之间进行 B.函数重载只能在全局函数之间进行 C.函数重载可以在基类和派生类之间进行 D.函数重载必须要求同名的函数的形参类型和个数都完全一致,返回值类型无所谓 3.下列运算符中不能重载的是( )。 A.∷(域运算符) B.+ (正) C.++ (自增) D.*(指针) 4. 派生类的对象对它的基类成员中() A. 公有继承的公有成员是可以访问的 B. 公有继承的私有成员是可以访问的 C. 公有继承的保护成员是可以访问的 D. 私有继承的公有成员是可以访问的 5 不能重载的运算符是() A. ?: B. [ ] C. new D. && 6. C++中不能重载的运算符是( ) A. new B. += C. sizeof D. && 7.重载函数是( ) A.以函数参数来区分,而不用函数的返回值来区分不同的函数 B.以函数的返回值来区分,而不用函数参数来区分不同的函数 C.参数表完全相同而返回值类型不同的两个或多个同名函数 D.参数表和返回值类型中至少有一个不同的两个或多个同名函数 8.对于运算符重载,说法正确的是( ) A.运算符如果被重载为非成员函数,那么对象就不能利用这个运算符重载函数进行操作 B.运算符重载函数可能既不是成员函数,也不是友元函数 C.用户每定义一个类,系统会自动提供一个赋值运算符重载函数,所以完全不 必考虑重载赋值运算符函数 D.一个类的虚函数不能调用运算符重载函数 9. C++中不能重载的运算符是( ) 实验十运算符重载1.实验目的及要求 1)掌握运算符重载的基本概念和方法。 2)熟习几种特殊的运算符的重载。 2.实验内容 1.分析下面的程序,指出程序运行的结果: 1) #include 运行结果为: 30,30 Press any key to continue 2)分析下面程序,指出程序运行的结果: #include 国家二级C++机试(运算符重载、模板和C++流)模拟试卷7 (总分:58.00,做题时间:90分钟) 一、选择题(总题数:29,分数:58.00) 1.下列关于函数模板的描述中,正确的是( )。 (分数:2.00) A.函数模板是一个实例函数 B.使用函数模板定义的函数没有返回类型 C.函数模板的类型参数与函数的参数相同 D.通过使用不同的类型参数,可以从函数模板得到不同的实例函数√ 解析:解析:函数模板是一系列相关函数的模型或样板,这些函数的源代码相同,只是所针对的数据类型不同。数据类型成了函数模板的参数,所以函数模板是一种参数化类型的函数。 2.有如下函数模板定义: template<typename T1,Typename T2> T1 Fun(T2 n){ return n*5.0;} 若要求以int型数据9作为函数实参调用该模板,并返回一个double型数据,则该调用应表示为( )。 (分数:2.00) A.FUN(9) B.FUN<9> C.FUN<double>[9] √ D.FUN<9>(double) 解析:解析:根据函数模板的定义,在选项C的调用中,把double类型传递给T1,int型传递给T2。 3.下列关于模板的描述中,错误的是( )。 (分数:2.00) A.类模板的成员函数都是模板函数 B.函数模板是一种参数化类型的函数 C.满足一定条件时可以省略模板实参 D.模板形参只能由关键字typename声明√ 解析:解析:同一模板的声明和定义中,模板形参的名字不必相同。每个模板类型形参前面必须带上关键字typename/class,每个非类型形参前面必须带上类型名字。 4.已知主函数中通过如下语句序列实现对函数模板swap的调用: int a[10],b[10]; swap(a,b,10);下列对函数模板swap的声明中,会导致上述语句序列发生编译错误的是( )。 (分数:2.00) A.template<typename T> void swap(T a[],T b[],int size); B.template<typename T> void swap(int size,T a[],T b[]);√ C.template<typename T1,typename T2> void swap(T1 a[],T2 b[],int size}; D.template<class T1,class T2> void swap(T1 a[],T2 b[],int size); 解析:解析:由题目中函数swap(a,b,10)调用语句可知,在对函数模板swap的声明语句中,应将第一、二个参数设为数组变量,第三个参数为整型变量。 5.在定义函数模板或类模板时,开头的保留字是( )。 (分数:2.00) A.typename B.template √ C.class D.typedef 解析:解析:定义函数模板或类模板时,开头的保留字是template。 6.若有函数模板mySwap和一些变量定义如下:( )。template<class T>void mySwap(T x,T y);double d1,d2;int i1,i2;下列对mySwap的调用中,错误的是 (分数:2.00) A.mySwap(i1,i2) . 《面向对象程序设计》习题 班级:学号:姓名:名单序号:成绩: 第7章运算符重载和多态性 一、选择题(共30分,每题1分) 1.下列运算符中,()运算符在C++中不能重载。 A.?: B.[] C. new D.++ 2.友元重载运算符obj1>obj2被C++编译器解释为()。 A.operator >(obj1,obj2) B.>(obj1,obj2) C.obj2.operator >(obj1) D.obj1.operator >(obj2) 3.重载赋值操作符时,应声明为()函数。 A.友元B.虚C.成员D.多态 4.在重载一个运算符时,其参数表中没有任何参数,这表明该运算符是()。 A. 作为友元函数重载的1元运算符 B. 作为成员函数重载的1元运算符 C. 作为友元函数重载的2元运算符 D. 作为成员函数重载的2元运算符5.在重载一运算符时,若运算符函数的形参表中没有参数,则不可能的情况是()。 A. 该运算符是一个单目运算符。 B. 该运算符函数有一个隐含的参数this。 C. 该运算符函数是类的成员函数。 D. 该运算符函数是类的友元函数。 6. 关于运输符重载,下列表述中正确的是()。 A.C++已有的任何运算符都可以重载 B.运算符函数的返回类型不能声明为基本数据类型 . C.在类型转换符函数的定义中不需要声明返回类型 D.可以通过运算符重载来创建C++中原来没有的运算符 7. C ++流中重载的运算符>>是一个()。 A. 用于输出操作的非成员函数 B. 用于输出操作的成员函数 C. 用于输入操作的非成员函数 D. 用于输入操作的成员函数 8. 若要对Data类中重载的加法运算符成员函数进行声明,下列选项中正确的是()。 A. Data +(Data); B. Data operator+(Data); C. Data +operator(Data); D. operator +(Data, Data); 9. 下列运算符中哪些是不能够被重载的()。 A. .,.*,sizeof,::,?: B. ++,--,new,= = C. new,delete,>=,[ ] D. +,-,=,delete 10. 在名为BigNumber类的类体中对运算符函数double进行如下声明: operator double(BigNumbe); 函数声明中有一个明显的错误,这个错误就是()。 A.参数表中不应该有任何参数 B.缺少对函数返回类型的说明 C.参数声明中缺少参数变量 D.函数声明中缺少函数体 11. 下列关于运算符重载的描述中,正确的是()。 A. 运算符重载成为成员函数时,若参数表中无参数,重载是一元运算符 B. 一元运算符只能作为成员函数重载 C. 二元运算符重载成为非成员函数时,参数表中有一个参数 实验五运算符重载、继承 ●实验目的 1、了解类的两种使用方式。 2、学习从现有类派生出新类的方式。 3、了解在派生类中如何使用基类的成员。 4、了解基类成员在派生类中的访问控制。 5、掌握运算符重载的方法。 ●实验内容 1、从类Person中派生出一个教师类,新增的属性有专业(Specialty)、职称(Position)和主讲课程(MajorCourse,一门),并为这些属性定义相应的方法。 [实现要求] Person类的设计如下,请将空白处补充完整。 class Person { string Name; int Age; string Sex; public: void Register(char *name,int age,char *sex) { ; Age=age; Sex=sex; } string GetName() { } string GetSex() { return Sex; } int GetAge() { } void ShowMe() { cout< //带参数的构造函数去初始化各个成员的值,使其显示运行结果的第一行t.TeacherRegister("张三",40, "f","计算机","副教授","C++"); t.ShowMe(); return 0; } 运行结果如下: XXX m 0 XXX XXX XXX 张三 f 40 计算机副教授C++ [思考问题] ①在Teacher类中是否要需要重新定义ShowMe成员函数?不重新定义ShowMe成员函数能否得到上述要求的运行结果?为什么? 2、从Point类中派生出一个Line类。Line类增加一个数据成员EndPoint,计算线的长度。 [实现提示] Point类可以按下面方式进行设计: class Point{ int x,y; public: Point(int a=0,int b=0){SetPoint(a,b);} void SetPoint(int a,int b); //设置点的坐标值 int GetX(){return x;} int GetY(){return y;} void Print(); //显示点的坐标值 }; Line类增加一个数据成员EndPoint为Point类对象,注意在设计Line类的构造函数时应为其基类和对象成员EndPoint提供形参。 为了检验Line类的功能,主函数按如下方式设计: int main(){ Line line(1,1,10,10); cout<<"Line line:"; line.Print(); cout<<"\n线line的长度:"; cout< //定义Student类,Date类,类定义与成员函数,实现分离。 //将Student类声明为Date的友元类。Student类需要提前声明。 //Student类的成员函数可以访问Date类的私有成员。 //成员函数:构造函数,构造函数重载,析构函数, //输出函数,求成绩最低者函数,排序函数。 //使用new,delete,动态分配内存。实现班级人数不固定,可以从键盘输入。 //定义Doctor类(研究生)-公共继承于Student类 //增加私有成员:string thesis(论文评价),int sci_value(科研分值) //增加相应的成员函数 //增加友元函数-运算符重载<<,>> //增加成员函数--按照科研分值高低排序 //student.h---头函数,类的定义 #include 一、运算符重载的规则 运算符重载规则如下: ①、C++中的运算符除了少数几个之外,全部可以重载,而且只能重载C++中已有的运算符。 ②、重载之后运算符的优先级和结合性都不会改变。 ③、运算符重载是针对新类型数据的实际需要,对原有运算符进行适当的改造。一般来说,重载的功能应当与原有功能相类似,不能改变原运算符的操作对象个数,同时至少要有一个操作对象是自定义类型。 不能重载的运算符只有五个,它们是:成员运算符“.”、指针运算符“*”、作用域运算符“::”、“sizeof”、条件运算符“?:”。 运算符重载形式有两种,重载为类的成员函数和重载为类的友元函数。 运算符重载为类的成员函数的一般语法形式为: 函数类型 operator 运算符(形参表) { 函数体; } 运算符重载为类的友元函数的一般语法形式为: friend 函数类型 operator 运算符(形参表) { 函数体; } 其中,函数类型就是运算结果类型;operator是定义运算符重载函数的关键字;运算符是重载的运算符名称。 当运算符重载为类的成员函数时,函数的参数个数比原来的操作个数要少一个;当重载为类的友元函数时,参数个数与原操作数个数相同。原因是重载为类的成员函数时,如果某个对象使用重载了的成员函数,自身的数据可以直接访问,就不需要再放在参数表中进行传递,少了的操作数就是该对象本身。而重载为友元函数时,友元函数对某个对象的数据进行操作,就必须通过该对象的名称来进行,因此使用到的参数都要进行传递,操作数的个数就不会有变化。 运算符重载的主要优点就是允许改变使用于系统内部的运算符的操作方式,以适应用户自定义类型的类似运算。 一般说来,单目运算符最好被重载为成员;对双目运算符最好被重载为友元函数,双目运算符重载为友元函数比重载为成员函数更方便此,但是,有的双目运算符还是重载为成员函数为好,例如,赋值运算符。 二、运算符重载为成员函数 对于双目运算符B,如果要重载B为类的成员函数,使之能够实现表达式oprd1 B oprd2,其中oprd1为类A的对象,则应当把B重载为A类的成员函数,该函数只有一个形参,形参的类型是oprd2所属的类型。经过重载后,表达式oprd1 B oprd2 就相当于函数调用 oprd1.operator B(oprd2). 《面向对象程序设计》习题 班级:学号:姓名:名单序号:成绩: 第7章运算符重载和多态性 一、选择题(共30分,每题1分) 1.下列运算符中,()运算符在C++中不能重载。 A.?: B.[] C. new D.++ 2.友元重载运算符obj1>obj2被C++编译器解释为()。 A.operator >(obj1,obj2) B.>(obj1,obj2) C.obj2.operator >(obj1) D.obj1.operator >(obj2) 3.重载赋值操作符时,应声明为()函数。 A.友元B.虚C.成员D.多态 4.在重载一个运算符时,其参数表中没有任何参数,这表明该运算符是()。 A. 作为友元函数重载的1元运算符 B. 作为成员函数重载的1元运算符 C. 作为友元函数重载的2元运算符 D. 作为成员函数重载的2元运算符5.在重载一运算符时,若运算符函数的形参表中没有参数,则不可能的情况是()。 A. 该运算符是一个单目运算符。 B. 该运算符函数有一个隐含的参数this。 C. 该运算符函数是类的成员函数。 D. 该运算符函数是类的友元函数。 6. 关于运输符重载,下列表述中正确的是()。 A.C++已有的任何运算符都可以重载 B.运算符函数的返回类型不能声明为基本数据类型 C.在类型转换符函数的定义中不需要声明返回类型 D.可以通过运算符重载来创建C++中原来没有的运算符 7. C ++流中重载的运算符>>是一个()。 A. 用于输出操作的非成员函数 B. 用于输出操作的成员函数 C. 用于输入操作的非成员函数 D. 用于输入操作的成员函数 8. 若要对Data类中重载的加法运算符成员函数进行声明,下列选项中正确的是()。 A. Data +(Data); B. Data operator+(Data); C. Data +operator(Data); D. operator +(Data, Data); 9. 下列运算符中哪些是不能够被重载的()。 A. .,.*,sizeof,::,?: B. ++,--,new,= = C. new,delete,>=,[ ] D. +,-,=,delete 10. 在名为BigNumber类的类体中对运算符函数double进行如下声明: operator double(BigNumbe); 函数声明中有一个明显的错误,这个错误就是()。 A.参数表中不应该有任何参数 B.缺少对函数返回类型的说明 C.参数声明中缺少参数变量 D.函数声明中缺少函数体 11. 下列关于运算符重载的描述中,正确的是()。 实验十六运算符重载 一、实验目的 1、理解运算符重载作用和意义; 2、掌握类运算符和友元运算符重载的定义和使用; 3、掌握常用运算符(++、--、+、-、*、/、=、+=、-=、*=、/=、<<(插入)、>>(提取))的重载。 二、实验内容 1、下列程序定义了一个复数类,重载"+"运算符以实现复数的加法运算。 #include #include return false; } bool operator <(Date &d1,Date &d2) { if(d1.year 实验5 运算符重载 1.实验目的 通过本次实验 (1)理解运算符重载函数的概念; (2)掌握运算符重载函数的定义与使用方法; 2.实验要求 (1)编写实验程序 (2)在运行环境中,输入源程序 (3)编译运行源程序 (4)输入测试数据进行程序测试; (5)写出运行结果。 3.实验内容 (1)定义一个复数类,重载“-=”运算符,使这个运算符能直接完成复数的“-=”运算。分别用成员函数与友元函数编写运算符重载函数。在主函数中定义复数对象c1(10,20)、c2(15,30),进行c2-=c1的复数运算,并输出c1、c2的复数值。 (2)定义一个数组类Array,其私有数据成员为整型一维数组a[10]。通过构造函数给a[10]赋初值。用Show函数显示a[10]的元素值。用成员函数重载运算符“+”,直接实现两个一维数组对应元素相加的运算。在主函数中定义数组a、b分别为: int a[10]={1,2,3,4,5,6,7,8,9,10}; int b[10]={4,5,6,7,8,9,10,11,12,13}; 用Array定义三个数组对象arr1(a)、arr2(b)、arr3,执行arr3=arr1+arr2运算,输出arr3的数组元素值。 (3)定义一个人民币类Money,类中数据成员为元、角、分。用成员函数与友元函数重载“――”运算符,实现人民币对象的减1运算。在主函数中定义人民币对象m1=10元8角5分及对象m2、m3。对m1作前置“――”并赋给m2。对m1作后置“――”并赋给m3。显示m1、m2、m3的结果。 (4)定义描述字符串的类String,编写字符串运算符“+=”的重载函数,使运算符“+=”用于两个字符串联接操作,即用str1+=str2实现字符串函数strcat(str1,str2)的操作功能。要求分别用成员函数与友元函数编写运算符重载函数。在主函数中定义字符串对象s1("software and ")与s2("hardware"),进行s1+=s2的字符串联接,并输出s1、s2的值。 Task8-1 /* 1. 定义一个复数类Complex,重载运算符“+”,使之能用于复数的加法运算。将运算符函数重载为非成员、非友元的普通函数。编写程序,求两个复数之和*/ #include Task8-2 /*2. 定义一个复数类Complex,重载运算符“+”、”-“、”*”、”/”, 使之能用于复数的加、减、乘、除。运算符重载函数作为Complex类的成员函数,编程,分别求两个复数之和差积商。 */ #include C++中预定义的运算符的操作对象只能是基本数据类型,实际上,对于很多用户自定义类型,也需要有类似的运算操作。例如: class complex { public: complex(double r=0.0,double I=0.0){real=r;imag=I;} void display(); private: double real; double imag; }; complex a(10,20),b(5,8); “a+b”运算如何实现?这时候我们需要自己编写程序来说明“+”在作用于complex类对象时,该实现什么样的功能,这就是运算符重载。运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用于不同类型的数据导致不同类型的行为。 运算符重载的实质是函数重载。在实现过程中,首先把指定的运算表达式转化为对运算符函数的调用,运算对象转化为运算符函数的实参,然后根据实参的类型来确定需要调用达标函数,这个过程爱编译过程中完成。 一、运算符重载的规则 运算符重载规则如下: ①、C++中的运算符除了少数几个之外,全部可以重载,而且只能重载C++中已有的运算符。 ②、重载之后运算符的优先级和结合性都不会改变。 ③、运算符重载是针对新类型数据的实际需要,对原有运算符进行适当的改造。一般来说,重载的功能应当与原有功能相类似,不能改变原运算符的操作对象个数,同时至少要有一个操作对象是自定义类型。 不能重载的运算符只有五个,它们是:成员运算符“.”、指针运算符“*”、作用域运算符“::”、“sizeof”、条件运算符“?:”。 运算符重载形式有两种,重载为类的成员函数和重载为类的友元函数。 运算符重载为类的成员函数的一般语法形式为: 函数类型 operator 运算符(形参表) { 函数体; } 运算符重载为类的友元函数的一般语法形式为: friend 函数类型 operator 运算符(形参表) { 函数体; } 其中,函数类型就是运算结果类型;operator是定义运算符重载函数的关键字;运算符是重载的运算符名称。 当运算符重载为类的成员函数时,函数的参数个数比原来的操作个数要少一个;当重载为类 运算符重载的应用 【实验目的】 1、理解重载运算符的意义。 2、掌握用成员函数、友元函数重载运算符的特点。 3、掌握重载运算符函数的调用方法。 【实验内容】 1.定义一个复数类,通过重载运算符:*,/,直接实现二个复数之间的乘除运算。编写 一个完整的程序,测试重载运算符的正确性。要求乘法“*”用友元函数实现重载,除法“/” 用成员函数实现重载。 ⑴分析 两复数相乘的计算公式为:(a+b i)*(c+d i)=(ac–bd )+(ad+bc) i 两复数相除的计算公式为:(a+b i)/(c+d i)=(ac+bd)/(c*c+d*d)+(bc-ad)/(c*c+d*d) i 复数类及运算符重载函数可定义为: 2.根据下面描述定义完整的日期类: class Date{ //成员变量 void IneDay();//日期增加1天 int DayCalc()const;//距基准日期的天数 static const int day[];//每月的天数 public: Date(int y,int m,int d); Date(int m, int d); Date(); void SystmDate();//读取系统当前时间 void SetDate(int yy,int mm,int dd);//设置日期 void SetDate(int mm,int dd); bool IsLeapYear(int yy) const;//是否闰年 bool IsEndofMonth()const ;//是否月末 //重载cout<<,cout>>完成读入和输出日期工作 //重载+,+=,-,-=,++,--,等运算符,完成日期的运算符操作。 //成员函数:判读一个日期是否是系统的当前日期 二、运算符重载(运算符重载的基本概念、运算符重载方法、运算符重载规则、特殊运算符重载和类型转换) 单选题10道: 1、假定要对类AB定义加号操作符重载成员函数,实现两个AB类对象的加法,并返回相加结果,则该成员函数的声明语句为( B )。 A. AB operator+(AB& a,AB& b) B. AB operator+(AB& a) C. operator+(AB a) D. AB &operator+( ) 2、关于运算符重载,下面的叙述错误的是()。 A.运算符预定义的操作数个数不能改变 B.重载不能改变运算符的优先级顺序 C.参数的类型没有限制 D.尽量使其与原意保持一致 3、在一个类中可以对一个操作符进行(D )重载。 A. 1种 B. 2种以下 C. 3种以下 D. 多种 4、重载赋值操作符时,应声明为(C )函数。 A. 友元 B. 虚 C. 成员 D. 多态 5、要在类对象使用运算符,以下不必被重载的运算符是( A )。 A. [] B. = C. ++ D. -- 6、下列运算符中,不能重载的是(C ) A.new B.() C.::D.&& 7、在表达式x+y*z中,+ 是作为成员函数重载的运算符,*是作为非成员函数重载的运算符。下列叙述中正确的是( A )。 A)operator+有两个参数,operator*有两个参数 B)operator+有两个参数,operator*有一个参数 C)operator+有一个参数,operator*有两个参数 D)operator+有一个参数,operator*有一个参数 8、友元运算符obj1>obj2被C++编译器解释为()。 A) operator>(obj1,obj2) B) >(obj1,obj2) C) obj1.operator>(obj2) D) obj2.operator>(obj1) 9、已知某个类的友元函数重载了+=和-,a,b,c是该类的对象,则“a+=b-c”被C++编译器解释为()。 A) operator+=(a,operator-(b,c)) B) a.operator+=(b.operator-(c)) C) operator+=(a,b.operator-(c)) D) a.operator+=(operator-(b,c)) 10、下列运算符中,必须使用成员函数进行重载的是()。 A) == B) = C) >> D) ++ 填空题10道: 1、多数运算符既能作为类的成员函数重载,也能作为类的非成员函数重载,但运算符“[]”只能作为类的函数重载。 2、加法运算符“+”和赋值运算符“=”都重载之后,“+=”也被重载了。 3、单目运算符作为类的成员函数重载时形参。 4、利用成员函数对二元运算符重载时,其右操作数为。 5、重载运算符函数的函数名由关键字引出。 6、运算符的重载归根结底是的重载。 7、后缀自增自减运算符定义时带有一个。实验8--友元函数与运算符重载函数
运算符重载练习题.
实验五 运算符重载
第十章 运算符重载 复习题
实验十_运算符重载
国家二级C++机试(运算符重载、模板和C++流)模拟试卷7
运算符重载知识题
实验5-运算符重载、继承 ( 1 )
Student类(友元,运算符重载,继承)综合题
C++运算符重载
第7章 运算符重载-习题
实验十六运算符重载解读
关系运算符重载实例2015
实验5 运算符重载
c++运算符重载习题
C++运算符重载讲解与经典实例 (2)
运算符重载实验
运算符重载题目