运算符重载实验报告

| 浏览次数:

 实

  验

  报

  告

 课程名称

  程序设计语言 C/C++

  实验项目

  运算符重载

 一、 实验目的

 1、 理解重载运算符的意义;

  2、 掌握成员函数、友元函数重载运算符的定义及使用方法;

  3、 掌握动态联编、虚函数、纯虚函数和抽象类的概念; 4、 掌握虚函数、纯虚函数和抽象类的定义及使用方法。

 二、 实验内容

 1.上机分析下面程序,掌握运算符重载的方法。

 要求:

 (1)给出实验结果; (2)掌握重载“+、-、—、=”运算符重载的方法。

 #include <iostream> using namespace std;

 class COMPLEX

 {

 public:

 COMPLEX(double r = 0, double i = 0);

 //构造函数

  COMPLEX(const COMPLEX& other);

 //拷贝构造函数

  void print();

  //打印复数

  COMPLEX operator +(const COMPLEX& other);

  //重载加法运算符(二元)

  COMPLEX operator -(const COMPLEX& other);

  //重载减法运算符(二元)

  COMPLEX operator -();

  //重载求负运算符(一元)

  COMPLEX operator =(const COMPLEX& other);

  //重载赋值运算符(二元)

 protected:

  double real, image;

  // 复数的实部与虚部

 };

  COMPLEX::COMPLEX(double r,double i) {

 real=r;

  image=i; }

 COMPLEX::COMPLEX(const COMPLEX& other)

 {

  real=other.real;

 image=other.image; }

 void COMPLEX::print() {

 cout<<real;

 if(image>0)

  cout<<"+"<<image<<"i";

 else if(image<0)

 cout<<image<<"i";

 cout<<endl; }

 COMPLEX

 COMPLEX::operator +(const COMPLEX& other) {

  COMPLEX temp;

  temp.real=real+other.real;

 //real=real+other.real;

 temp.image=image+other.image;

 //image=image+other.image;

 return temp;

 //*this; }

 COMPLEX COMPLEX::operator -(const COMPLEX& other) {

 COMPLEX temp;

 temp.real=real-other.real;

 temp.image=image-other.image;

 return temp;

 }

 COMPLEX COMPLEX::operator -() {

  COMPLEX temp;

 temp.real=-real;

 temp.image=-image;

 return temp; }

 COMPLEX COMPLEX::operator =(const COMPLEX& other) {

  real=other.real;

 image=other.image;

 return *this;

 //返回对象值 }

  int main()

 {

  COMPLEX c1(1, 2);

  // 定义一个值为 1 + 2i 的复数 c1

  COMPLEX c2(2);

 // 定义一个值为 2 的复数 c2

  COMPLEX c3(c1);

  // 用 COMPLEX(const COMPLEX& other)创建一个值同 c1 的新复数

  c3.print();

  // 打印 c3 原来的值

  c1=c1+c2+c3;

 // 将 c1 加上 c2 再加上 c3 赋值给 c1

  c2=-c3;

  // c2 等于 c3 求负

  c3=c2-c1;

  // c3 等于 c2 减去 c1

  c3.print();

  // 再打印运算后 c3 的值

  cout<<sizeof(c1)<<endl;

  return 0;

 } 2. 上机分析下面程序,给出输出结果。

 要求:

 (1)给出实验结果;

 (2)掌握友元运算符重载的基本方法:通过重载 cout 语句,可使用 cout 输 出对象的数据成员值的方法。

 #include<iostream.h> class T {

  int x,y;

  public:

 T(int a,int b)

 {x=a;y=b;}

 friend ostream & operator<<(ostream &os, T &a); };

 ostream & operator<<(ostream &os,T &a) { os<<"x="<<a.x<<"

 y="<<a.y;

  return os; }

  void main() {

  T a(1,2);

 cout<<a<<endl; }

  3、上机分析下面程序,掌握抽象类、纯虚函数以及动态绑定的定义和使用。

 要求:

 (1)给出实验结果;

 (2)掌握抽象类、纯虚函数以及动态绑定的方法。

 // shape.h 文件 定义抽象基类 Shape

 #ifndef SHAPE_H #define SHAPE_H class Shape {

  public:

 virtual double Area() const

 {

  return 0.0;

  }

 // 纯虚函数,在派生类中重载

 virtual void PrintShapeName() const = 0;

 virtual void Print() const = 0; }; #endif

  // point.h 文件 定义类 Point #ifndef POINT_H #define POINT_H #include <iostream> using namespace std; class Point : public Shape {

 int x, y;

  //点的 x 和 y 坐标

  public:

 Point( int = 0, int = 0 );

 // 构造函数

 void SetPoint( int a, int b );

 // 设置坐标

 int GetX() const // 取 x 坐标

 {

  return x;

 }

 int GetY() const // 取 y 坐标

 {

  return y;

 }

 virtual void PrintShapeName() const

 {

  cout << "Point: ";

 }

 virtual void Print() const; //输出点的坐标 }; #endif

 // Point.cpp 文件

 Point 类的成员函数定义

 #include <iostream> using namespace std;

 Point::Point( int a, int b ) : x( a ), y( b )

 { } void Point::SetPoint( int a, int b )

 {

 x = a;

 y = b; }

 void Point::Print() const

 {

 cout << "[" << x << ", " << y << "]"; }

  // circle.h 定义类 Circle

 #ifndef CIRCLE_H

 #define CIRCLE_H

 #include <iostream> using namespace std;

 class Circle : public Point

 {

 double radius;

 public:

 Circle(int x = 0, int y = 0, double r = 0.0);

  void SetRadius( double r );

 //设置半径

 double GetRadius() const;

 //取半径

 virtual double Area() const;

 //计算面积 a

 virtual void Print() const;

  //输出圆心坐标和半径

 virtual void PrintShapeName() const

 {

  cout << "Circle: ";

  }

 };

 #endif

 // circle.cpp 文件

 circle 类的成员函数定义

 Circle::Circle(int a,int b,double r): Point(a,b), radius( r )

 { }

 void Circle::SetRadius( double r )

 {

 radius = ( r >= 0 ? r : 0 );

  }

 double Circle::GetRadius() const

  {

  return radius;

  }

 double Circle::Area() const

 {

  return 3.14159 * radius * radius; }

 void Circle::Print() const

 {

 cout << "Center = ";

 Point::Print();

 cout << "; Radius = " << radius << endl;

 }

 //main.cpp 文件 演示图形类

 #include <iostream>

 using namespace std;

 void virtualViaPointer( const Shape * );

 void virtualViaReference( const Shape & );

 int main()

 {

  Point point(30,50);

  //创建 point、circle 对象

 Circle circle(120,80,10.0);

 point.PrintShapeName();

  //输出 point、circle、rectangle 对象信息

 point.Print();

  cout << endl;

  circle.PrintShapeName();

  circle.Print();

  Shape *arrayOfShapes[2];

  //定义基类对象指针

 arrayOfShapes[ 0 ] = &point;

  arrayOfShapes[ 1 ] = &circle;

  cout << "Virtual function calls made off " << "base-class pointers\n";

 //通过基类对象指针访问派生类对象

  for ( int i = 0; i < 2; i++ )

  {

 virtualViaPointer( arrayOfShapes[ i ] );

  }

 cout << "Virtual function calls made off " << "base-class references\n";

 for ( int j = 0; j < 2; j++ )

 {

 virtualViaReference( *arrayOfShapes[ j ] );

  }

 return 0; } void virtualViaPointer( const Shape *baseClassPtr )

 //通过基类对象指针访问虚函数实现动态绑定

 {

  baseClassPtr->PrintShapeName();

 baseClassPtr->Print();

  cout << "Area = " << baseClassPtr->Area() << endl;

 } //通过基类对象引用访问虚函数实现动态绑定

 void virtualViaReference( const Shape &baseClassRef ) {

  baseClassRef.PrintShapeName();

  baseClassRef.Print();

 cout << "Area = " << baseClassRef.Area() << endl; } 4、上机完成下面实验。

 声明一个 Shape(形状)基类,它有两个派生类:Circle(圆)和 Square(正方形),要求利用多态性的概念,分别以虚函数的形式完成对圆和正方形的周长及面积的计算。

 要求:Shape 类的数据成员包括中心点的坐标,Circle 类和 Square 类初始值分别给出:

 圆的圆心和半径;正方形的中心和一个顶点。

 【实例编程】(参考)

 实数矩阵类 //头文件 MatrixException.h

 #include <stdexcept>

 #include <string>

 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

 {

  private:

 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 <iostream>

 #include <strstream>

 #include <string>

 //#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)

 {

 if( this == &b )

 {

  return *this;

 }

 if ( col != b.col || row !=b.row

 )

 {

  throw( IncompatibleDimension(" Matrix "+int2String(row)

 + " x " + int2String(col) + " equails matrix "

 + int2String(b.row) + " x " + int2String(b.col)+".") );

 }

  row = b.row;

 col = b.col;

 delete []elems;

 if ( NULL == b.elems )

  {

 elems = NULL;

 }

 else

  {

 int total = row*col;

  elems = new double[total];

  for( int i = 0; i < total; ++i )

  {

 elems[i] = b.elems[i];

  }

 }

  return *this;

 } //重载运算符"( )"可以由给出的矩阵行列得到相应的矩阵元素值。之所以重载"( )"而不是"[]",是因为避免数组 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)

 {

 if ( col != b.row )

  // incompatible dimensions

 {

  throw(IncompatibleDimension(" Matrix "+int2String(row)

 + " x " + int2String(col) + " times matrix "

 + int2String(b.row) + " x " + int2String(b.col)+"."));

 }

 Matrix ans(row, b.col);

 for (int r=0 ; r < row ; r++)

 {

 for (int c=0 ; c < b.col; c++)

  {

 ans.SetElem(r, c, rowTimesCol(r, b, c) );

 }

 }

 return ans; }

 Matrix Matrix::operator +(const Matrix& b) const throw(IncompatibleDimension)

 {

 if ( col != b.col || row !=b.row

 )

  {

 throw(IncompatibleDimension(" Matrix "+int2String(row)

 + " x " + int2String(col) + " adds matrix "

 + int2String(b.row) + " x " + int2String(b.col)+"."));

 }

 Matrix ans(row, col);

 for (int r=0 ; r < row ; r++)

 {

 for (int c=0 ; c < col; c++)

 {

  ans.SetElem(r, c, elems[r*col+c]+b.elems[r*col+c]);

 }

 }

 return ans;

 }

 Matrix Matrix::operator -(const Matrix& b) const throw(IncompatibleDimension)

 {

 if ( col != b.col || row !=b.row

 )

  {

 throw( IncompatibleDimension(" Matrix "+int2String(row)

 + " x " + int2String(col) + " minus matrix "

 + int2String(b.row) + " x " + int2String(b.col)+".") );

 }

 Matrix ans(row, col);

 for (int r=0 ; r < row ; r++)

 {

 for (int c=0 ; c < col; c++)

 {

  ans.SetElem(r, c, elems[r*col+c]-b.elems[r*col+c]);

  }

 }

 return ans; }

 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<<endl;

  }

 cout<<endl;

 }

 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 <iostream>

 //#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:"<<endl;

 x1.Print();

 Matrix y1(b, 5, 3);

 cout<<"the matrix of y1 is:"<<endl;

 y1.Print();

 Matrix z1 = x1*y1;

 //两个矩阵相乘

 cout<<"the matrix of z1=x1*y1 is:"<<endl;

 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:"<<endl;

  x2.Print();

 cout<<"x1*x2 is:"<<endl;

  x1*x2;

  //两个维数不匹配矩阵相乘,产生异常

 cout<<"x1-x2 is:"<<endl;

 x1-x2;

  //两个维数不匹配矩阵相减,产生异常

  cout<<"Set a new element for x1:"<<endl;

 x1.SetElem (7, 8, 30);

 //设置矩阵元素超界,产生异常

 cout<<"Get a element from x1:"<<endl;

 x1(4, 5);

  // 取不存在的矩阵元素,产生异常

 }

  catch(MatrixException& e)

  {

  cout << e.what() << endl; //获取异常信息

 }

 return 0;

 } 三、实验 步骤 及结果分析

 1. 程序的类结构图为:

 COMPLEX

 #real:double #image:double +COMPLEX(double r=0,double i=0) +COMPLEX(const COMPLEX &other) +print():void

 +operator+(const COMPLEX &other): COMPLEX +operator-(const COMPLEX &other) : COMPLEX +operator-(): COMPLEX +operator=(const COMPLEX &other) : COMPLEX

 运行结果

 2. 程序的类结构图为:

 T T

 x, y:int

 +T(int a,int b)

 +&operator<<(ost ream &os,T &a):friend ostream

 运行结果

  3. 程序的类结构图为:

 Shape

 + +A A rea():virtual double

 const

 +PrintShapeName():virtual void

 const

 +Print():virtual void

 const

 Point x,y:int +Point(int=0,int=0)

 +SetPoint (in t a,int b):void

 +GetX():int const

 +G etY():int const

 +PointShapeName():virtual void const

 +Print():virtual void const

 Circle

 r r adius:double

 + + Circle(int x=0,int y=0,double r=0.0)

 + + SetRadius(double r):void

 + + GetRadius():double const

 + + Area():virtual dou ble con st

 + + Print():virtual void const

 + + PrintShapeName():virtual void const

  运行结果

 4. 程序的类结构图为:

 Shape1 1

 #x_size,y_size:double

 +Shape1 1 (double x,double y)

 +area():virtual double

 +perimeter():virtual double e

 +print():virtual void

 相关代码:

 #include<iostream>

 using namespace std; class Shape1 {

 protected:

 double x_size,y_size;

 public:

  Shape1(double x,double y);

 // 构造函数

  virtual double area()

  // 纯虚函数,在派生类中重载

  {

 return 0.0; Circle1 1

 #radiu s:double

 +Ci rcle 1 (double e

 x=0.0,double y=0.0,double r=0.0)

 +set_radius(double r=0.0):void

 +get_radius():double

 +area():virtual double

 +perimeter():virtual double

 +print():virtual void

 Square1 1

 #i_size,j_size: double

 +Square1 1 (double x=0.0,double y=0.0,

 d d ouble

 i=0.0 ,double j=0.0)

 +set_i(double i):void

 +set_j(double_j):void

 +get_i():void

 + +g g et_j():void

 +area():virtual double

 +perimeter():virtual double

 +print():virtual void

 }

  virtual double perimeter()

  {

 return 0.0;

  }

  virtual void print()=0; };

 Shape1::Shape1(double a,double b) {

 x_size=a;

 y_size=b; }

 class Circle1:public Shape1 {

 protected:

 double radius;

 public:

  Circle1(double x=0.0,double y=0.0,double r=0.0); // 构造函数

  void set_radius(double r=0.0);

  //设置半径

  double get_radius();

  //输出半径

  virtual double area();

  virtual double perimeter();

  virtual void print();

  //输出圆心坐标和半径 };

 Circle1::Circle1(double x,double y,double r):Shape1(x,y),radius(r)//构造函数 {} void Circle1::set_radius(double r) {

 radius=r; } double Circle1::get_radius() {

 return radius; } double Circle1::area() {

 return 3.14159*radius*radius; } double Circle1::perimeter() {

 return 3.14159*radius*2; } void Circle1::print()

  //输出圆心坐标 {

  cout<<"["<<x_size<<","<<y_size<<"]"<<", "<<radius; }

 class Square1:public Shape1 {

  protected:

 double i_size,j_size;

 public:

  Square1(double x=0.0,double y=0.0,double i=0.0,double j=0.0); // 构造函数

  void set_i(double i);

 //设置顶点横坐标

  void set_j(double j);

 //设置顶点纵坐标

  double get_i();

 //输出顶点横坐标

  double get_j();

 //输出顶点纵坐标

  virtual double area();

  virtual double perimeter();

  virtual void print();

 //输出中心坐标和顶点坐标

 };

 Square1::Square1(double x,double y,double i,double j):Shape1(x,y),i_size(i),j_size(j) {}

 void Square1::set_i(double i) {

 i_size=i; } void Square1::set_j(double j) {

 j_size=j; } double Square1::get_i() {

 return i_size; } double Square1::get_j() {

 return j_size; } double Square1::area() {

 return 2*(i_size-x_size)*2*(j_size-y_size); } double Square1::perimeter() {

 return 4*2*(i_size-x_size); } void Square1::print()

 {

 cout<<"["<<x_size<<","<<y_size<<"]"<<", "<<"["<<i_size<<","<<j_size<<"]"; }

 int main()

 {

  Circle1 circle(0.0,0.0,3.0);

  circle.area();

  circle.perimeter();

  circle.print();

 cout<<"\n";

  Square1 square(0.0,0.0,3.0,3.0);

  square.area();

  square.perimeter();

  square.print();

 cout<<"\n";

  cout<<"圆的面积为:"<<circle.area()<<endl;

  cout<<"圆的周长为:"<<circle.perimeter()<<endl;

  cout<<"圆的圆心坐标和半径为:";

 circle.print();

 cout<<"\n\n";

  cout<<"正方形的面积为:"<<square.area()<<endl;

  cout<<"正方形的周长为:"<<square.perimeter()<<endl;

  cout<<"正方形的中心坐标和一个顶点坐标分别为:";

 square.print();

  cout<<"\n";

 return 0; } 运行结果

 【实例编程】

 运行结果

推荐访问: 重载 运算符 实验

【运算符重载实验报告】相关推荐

工作总结最新推荐

NEW