运算符重载实验报告
实
验
报
告
课程名称
程序设计语言 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; } 运行结果
【实例编程】
运行结果
上一篇:生理心理学:牛蛙实验报告
下一篇:用友软件实验报告书