运算符重载和多态性

运算符重载和多态性
运算符重载和多态性

实验5 运算符重载和多态性班级学号(最后两位)姓名成绩

一、实验目的

1.掌握用成员函数重载运算符的方法

2.掌握用友元函数重载运算符的方法

3.理解并掌握利用虚函数实现动态多态性和编写通用程序的方法

4.掌握纯虚函数和抽象类的使用

二、实验内容

1.复数类加减法乘除运算(用成员函数定义运算符重载)。

复数类的定义:

class complex //复数类声明

{ public: //外部接口

complex(double r=0.0,double i=0.0) //构造函数

{real=r,imag=i;}

complex operator +(complex c2); //运算符"+"重载成员函数

complex operator - (complex c2); //运算符"-"重载成员函数

complex operator *(complex ); //运算符"*"重载成员函数

complex operator /(complex); //运算符"/"重载成员函数

complex operator =(complex c2); //运算符"="重载成员函数

void display(); //输出复数

private: //私有数据成员

double real; //复数实部

double imag; //复数虚部

};

实验代码:

#include

using namespace std;

class Complex

{

public:

Complex()

{

real=0;

imag=0;

}

Complex(double r,double i)

{

real=r;

imag=i;

}

Complex operator+(Complex &c2);

Complex operator-(Complex &c2);

Complex operator*(Complex &c2);

Complex operator/(Complex &c2);

void display();

private:

double real; double imag;

};

Complex Complex::operator+(Complex &c2)

{

Complex c;

c.real=real+c2.real;

c.imag=imag+c2.imag; return c;

}

Complex Complex::operator-(Complex &c2)

{

Complex c;

c.real=real-c2.real;

c.imag=imag-c2.imag;

return c;

}

Complex Complex::operator*(Complex &c2)

{

Complex c;

c.real=real*c2.real-imag*c2.imag;

c.imag=imag*c2.real+real*c2.imag; return c;

}

Complex Complex::operator/(Complex &c2)

{

Complex c;

c.real=(real*c2.real+imag*c2.imag)/(c2.real*c2.real+c2.imag*c2.imag);

c.imag=(imag*c2.real-real*c2.imag)/(c2.real*c2.real+c2.imag*c2.imag);

return c;

}

void Complex::display()

{cout<<"("<

int main()

{

Complex c1(4,7),c2(2,1),c3;

cout<<"c1=";

c1.display();

cout<<"c2=";

c2.display();

int i,j=1;

while(j)

{

cout<<"\n";

cout<<"\t\t"<<"1.复数之和\n";

cout<<"\t\t"<<"2.复数之差\n";

cout<<"\t\t"<<"3.复数之积\n";

cout<<"\t\t"<<"4.复数之商\n";

cout<<"\t\t"<<"0.退出\n";

cout<<"请选择(0--4) ";

cin>>i;

switch(i)

{

case 1: c3=c1+c2;

cout<<"c1+c2=";c3.display();

break;

case 2: c3=c1-c2;

cout<<"c1-c2=";

c3.display();break;

case 3: c3=c1*c2;

cout<<"c1*c2=";

c3.display();

break;

case 4: c3=c1/c2;

cout<<"c1/c2=";

c3.display();

break;

case 0: j=0;

break;

}

}

}

实验测试:

2.复数类比较运算(用友元函数定义运算重载)。

注意:

1)复数类比较运算按复数的模比较两个复数的大小。

2)复数相等判断当两个复数的实部和虚部都相等,两个复数才相等,否则不相等。

类的定义

class complex //复数类声明

{

public:

complex(double r=0.0,double i=0.0)

{real=r;imag=i;} //构造函数

friend int operator> (complex c1,complex c2); //运算符">"重载友元函数

friend int operator>=(complex c1,complex c2); //运算符">="重载友元函数

friend int operator <(complex c1,complex c2); //运算符"<"重载友元函数

friend int operator<=(complex c1,complex c2); //运算符"<="重载友元函数

friend int operator ==(complex c1,complex c2); //运算符"=="重载友元函数

friend int operator !=(complex c1,complex c2); //运算符"!="重载友元函数void display( ); //显示复数的值

private: //私有数据成员

double real;

double imag;

};

实验代码:

#include"iostream.h"

#include"math.h"

class complex

{

public:

complex(double r=0.0,double i=0.0)

{

real=r;imag=i;

}

friend bool operator> (complex c1,complex c2);

friend bool operator>=(complex c1,complex c2);

friend bool operator< (complex c1,complex c2);

friend bool operator<=(complex c1,complex c2);

friend bool operator==(complex c1,complex c2);

friend bool operator!=(complex c1,complex c2);

void display( );

private:

double real;

double imag;

};

bool operator>(complex c1,complex c2)

{

if(sqrt(c1.real*c1.real+c1.imag*c1.imag)>sqrt(c2.real*c2.real+c2.imag*c2.imag))

return true;

else

return false;

}

bool operator>=(complex c1,complex c2)

{

if(sqrt(c1.real*c1.real+c1.imag*c1.imag)>sqrt(c2.real*c2.real+c2.imag*c2.imag)||sqrt(c1.real*c1.r eal+c1.imag*c1.imag)==sqrt(c2.real*c2.real+c2.imag*c2.imag))

return true;

else

return false;

}

bool operator<(complex c1,complex c2)

{

if(sqrt(c1.real*c1.real+c1.imag*c1.imag)

return true;

else

return false;

}

bool operator<=(complex c1,complex c2)

{

if(sqrt(c1.real*c1.real+c1.imag*c1.imag)

return true;

else

return false;

}

bool operator==(complex c1,complex c2)

{

if(c1.real==c2.real&&c1.imag==c2.imag)

return true;

else

return false;

}

bool operator!=(complex c1,complex c2)

{

if(c1.real!=c2.real||c1.imag!=c2.imag) return true;

else

return false;

}

void complex::display()

{

cout<<"("<

}

void compare(complex &c1,complex &c2)

{

if(operator>(c1,c2)==1)

{c1.display();cout<<">";c2.display(); cout<=(c1,c2)==1)

{c1.display();cout<<">=";c2.display(); cout<

{c1.display();cout<<"<";c2.display(); cout<

{c1.display();cout<<"<=";c2.display(); cout<

{c1.display();cout<<"=";c2.display(); cout<

{c1.display();cout<<"!=";c2.display(); cout<

int main() {

complex c1(2,8),c2(3,6),c3(4,5);

cout<<"c1=";c1.display();

cout<

cout<<"c2=";c2.display();

cout<

cout<<"c3=";

c3.display();

cout<

compare(c1,c2);

compare(c1,c3);

compare(c2,c3);

return 0;

}

测试结果:

3.利用虚函数实现的多态性来求四种几何图形的面积之和。这四种几何图形是:三角形、矩形、正方形和圆。几何图形的类型可以通过构造函数或通过成员函数来设置。

⑴分析

计算这四种几何图的面积公式分别是:

三角形的边长为W,高为H时,则三角形的面积为W* H/2;矩形的边长为W,宽为H 时,则其面积为W* H;正方形的边长为S,则正方形的面积为S*S;圆的半径为R,其面积为3.1415926 *R *R。

为设置几何图形的数据并求出几何图形的面积,需要定义一个包含两个虚函数的类:class Shape

{public:

virtual float Area( void) =0; //求面积

virtual void Setdata(float ,float =0) =0; //设置图形数据

};

因面积的计算依赖于几何图形,故在类中只能定义一个纯虚函数Area。同理,设置几何图形数据的函数Setdata也只能定义为纯虚函数。

把这个基类派生出其它几何图形类。如派生出的三角形类为:

class Triangle:public Shape

{ float W,H; //三角形边长为W,高为H

public:

Triangle(float w=0,float h=0){ W=w; H = h; }

float Area( void){ return W*H/2; }

void Setdata(float w,float h=0){ W=w; H = h; }

};

实验代码:

#include

#define PI 3.1415926

using namespace std;

class Shape

{ public:

virtual float Area( void) =0;

virtual void show(void) =0;

};

class Triangle:public Shape

{ float W,H;

public:

Triangle(float w=0,float h=0){ W=w; H = h; }

float Area( void){ return W*H/2; }

void show()

{ cout<<"\n三角形:"<<" 边长:"<

}

};

class Rectangle:public Shape

{

float W,H;

public:

Rectangle(float w=0,float h=0):W(w),H(h){}

float Area(void){ return W*H; }

void show()

{ cout<<"\n\n矩形:"<<" 长:"<

<<" 矩形面积面积:"<

};

class Square:public Shape

{

float W;

public:

Square(float w=0):W(w){}

float Area(void){ return W*W; }

void show()

{ cout<<"\n\n正方形:"<<" 边长:"<

};

class Circle:public Shape

{

float radius;

public:

Circle(float r):radius(r){}

float Area(void){ return PI*radius*radius; }

void show()

{ cout<<"\n\n圆:"<<" 半径:"<

void main()

{ Shape *S;

Triangle T(1,4);

Rectangle R(6,2);

Square Sq(4);

Circle C(7);

S=&T; S->show();

S=&R; S->show();

S=&Sq; S->show();

S=&C; S->show();

}

测试结果:

运算符重载基础概念练习题

运算符重载基础概念练习题 1、下列运算符中, ()运算符在C++中不能重载。 A = B () C :: D delete 2、下列运算符中, ()运算符在C++中不能重载。 A ?: B [] C new D && 3、下列关于C++运算符函数的返回类型的描述中,错误的是()。 A 可以是类类型 B 可以是int类型 C 可以是void类型 D 可以是float类型 4、下列运算符不能用友元函数重载的是()。 A + B = C * D << 5、在重载运算符函数时,下面()运算符必须重载为类成员函数形式。 A + B - C ++ D -> 6、下列关于运算符重载的描述中,正确的是()。 A 运算符重载可以改变运算符的操作数的个数 B 运算符重载可以改变优先级 C 运算符重载可以改变结合性 D 运算符重载不可以改变语法结构 7、友元运算符obj>obj2被C++编译器解释为()。 A operator>(obj1,obj2) B >(obj1,obj2) C obj2.operator>(obj1) D obj1.oprator>(obj2) 8、在表达式x+y*z中,+是作为成员函数重载的运算符,*是作为非成员函数重载的运算符。下列叙述中正确的是()。 A operator+有两个参数,operator*有两个参数 B operator+有两个参数,operator*有一个参数 C operator+有一个参数,operator*有两个参数 D operator+有一个参数,operator*有一个参数 9、重载赋值操作符时,应声明为()函数。 A 友元 B 虚 C 成员 D 多态 10、在一个类中可以对一个操作符进行()重载。 A 1种 B 2种以下 C 3种以下 D 多种 11、在重载一个运算符时,其参数表中没有任何参数,这表明该运算符是()。

多态参考代码分析

1224: 多态-虚函数问题 Description 请以点类Point为基类派生出一个圆类Circle。Point类的数据成员为x、y(私有属性,存储点的横纵坐标),成员函数有构造函数Point(实现对数据成员x、y的初始化)、输出函数Display(输出点坐标);圆类Circle的数据成员为r(私有属性,存储圆的半径,圆心的点坐标通过继承点类Point加以实现),成员函数有构造函数Circle、计算圆的面积函数Area、计算圆的周长函数Perimeter和输出函数Display,其中构造函数实现基类和圆类的数据成员的初始化,Display函数实现圆心坐标、圆的半径、圆的面积(利用Area函数实现)和圆的周长(利用Perimeter函数实现)的输出。实现Point类和Circle类的定义及成员函数。主函数的代码(不允许改动)如下: int main() { double x,y,r; cin>>x>>y>>r; //圆心的点坐标及圆的半径 Point *p; p=new Point(x,y); p->Display(); p=new Circle(x,y,r); p->Display(); return 0; } 说明:圆周率PI的取值为3.14 提示:Display应设计为虚函数 Input Output Sample Input 0 0 1 Sample Output Point(0,0) Circle's center:Point(0,0) Radius:1 Area:3.14 Perimeter:6.28 **************************************************************** #include using namespace std; const double PI=3.14; class Point { private: double x,y; public:

实验报告类的重载继承和多态

实验报告类的重载继承和多态 篇一:实验三_类的重载继承和多态_() 篇二:实验三_类的重载继承和多态 篇三:C++实验报告(类和对象重载与继承多态和模板异常和流) C++实验报告 目录 C++实验报告 ................................................ ................................................... (4) 实验一:类和对象 ................................................ ................................................... . (4) 1................................................. ................................................... . (4) 代码 ................................................

................................................... .. (4) 运行结果 ................................................ ................................................... (5) 2.................................................. ................................................... (5) 思路: .............................................. ................................................... . (5) 代码 ................................................ ................................................... (5) 运行结果 ................................................ ...................................................

c 运算符的重载习题答案

1.概念填空题 1.1运算符重载是对已有的运算符赋予多重含义,使同一个运算符在作用于不同类型对象时导致不同的行为。运算符重载的实质是函数重载,是类的多态性特征。 1.2可以定义一种特殊的类型转换函数,将类的对象转换成基本数据类型的数据。但是这种类型转换函数只能定义为一个类的成员函数而不能定义为类的友元函数。类类型转换函数既没有参数,也不显式给出返回类型。类类型函数中必须有return 表达式的语句返回函数值。一个类可以定义多个类类型转换函数。 1.3运算符重载时其函数名由operator运算符构成。成员函数重载双目运算符时,左操作数是对象,右操作数是函数参数。 2.简答题 2.2简述运算符重载的规则。 2.2简述重载单目运算符++、--,前置和后置时的差别。 2.3 C++中重运算符是否都可以重载?是否都可以重载成类的成员函数?是否都可以重载成类的友元函数? 2.4 构造函数作为类型转换函数的条件是什么。 3.选择题 3.1在下列运算符中,不能重载的是(B) A.! B. sizeof C. new D. delete 3.2 不能用友员函数重载的是(A)。 A.= B.== C.<= D.++ 3.3下列函数中,不能重载运算符的函数是(B)。 A.成员函数 B.构造函数 C.普通函数 D.友员函数 3.4如果表达式++i*k时中的”++”和”*”都是重载的友元运算符,则采用运算符函数调用格式,该表达式还可表示为(B)。 A.operator*(i.operator++(),k) B.operator*(operator++(i),k) C.i.operator++().operator*(k) D.k.operator*(operator++(i)) 3.5已知在一个类体中包含如下函数原型:VOLUME operator-(VOLUME)const;下列关于这个函数的叙述中,错误的是(B )。 A.这是运算符-的重载运算符函数 B.这个函数所重载的运算符是一个一元运算符 C.这是一个成员函数 D.这个函数不改变数据成员的值 3.6在表达式x+y*z中,+是作为成员函数重载的运算符,*是作为非成员函数重载的运算符。下列叙述中正确的是(C )。 A.operator+有两个参数,operator*有两个参数 B.operator+有两个参数,operator*有一个参数 C.operator+有一个参数,operator*有两个参数 D.operator+有一个参数,operator*有一个参数 4.写出下列程序运行结果 4.1#include #using namesoace std;

C#中区别多态、重载、重写的概念和语法结构

重写是指重写基类的方法,在基类中的方法必须有修饰符virtual,而在子类的方法中必须指明override。 格式: 基类中: public virtual void myMethod() { } 子类中: public override void myMethod() { } 重写以后,用基类对象和子类对象访问myMethod()方法,结果都是访问在子类中重新定义的方法,基类的方法相当于被覆盖掉了。 重载 用于在给定了参数列表和一组候选函数成员的情况下,选择一个最佳函数成员来实施调用。 public void test(int x,int y){} public void test(int x,ref int y){} public void test(int x,int y,string a){} 重载特征: I.方法名必须相同 II.参数列表必须不相同,与参数列表的顺序无关 III.返回值类型可以不相同 ========================= 但如果有泛型,就要注意了! 多态 c#的多态性主要体现在类的继承上: 子类继承父类的时候,可能出现同名但方法定义不同的情况, 所以在子类中会将原方法覆盖,实现自身的要求. using System; class Employee { virtual public void CalculatePlay() { Console.WriteLine("Employee");

} }; class SalariedEmployee: Employee { override public void CalculatePlay() { Console.WriteLine("Salary"); } }; class PolyApp { public static void Main() { Employee baseE1 = new Employee(); baseE1.CalculatePlay(); Employee baseE2 = new SalariedEmployee(); baseE2.CalculatePlay(); SalariedEmployee s = new SalariedEmployee(); s.CalculatePlay();

习题10-运算符重载与多态性

C 、可以是void 类型 D 、可以是float 类型 A 、运算符重载可以改变运算符的操作数的个数 B 、运算符重载可以改变优先级 C 、运算符重载可以改变结合性 D 、运算符重载不可以改变语法结构 A 、动态联编是以虚函数为基础的 B 、动态联编是在运行时确定所调用的函数代码的 C 、动态联编调用函数操作是指向对象的指针或对象引用 D 、动态联编是在编译时确定操作函数的 A 、虚函数是一个静态成员函数 B 、虚函数是一个非成员函数 C 、虚函数既可以在函数说明时定义,也可以在函数实现时定义 D 、派生类的虚函数与基类中对应的虚函数具有相同的参数个数和类型 B 、重载函数和析构函数 C 、虚函数和对象 习题 10 运算符重载与多 态性 、单项选择题 A 、 ? : B 、 [ ] C 、 new D 、 && 2、 下列运算符不能用友元函数重载的是( )。 A 、 + B 、 = C 、 * D 、 << 3、 在一个类中可以对一个操作符进行( )重载。 A 、 1种 B 、 2 种以下 C 、 3 种以下 D 、 多种 4、友元运算符 obj1>obj2 被 C++ 编译器解释为( )。 1、下列运算符中,( )运算符在C++中不能重载。 A 、 operator > (obj1, obj2) B 、 > (obj1, obj2) C 、 obj2.operator > (obj1) D 、 obj1.operator > (obj2) 5、下列关于C++运算符函数的返回类型的描述中,错误的是( ) 。 A 、可以是类类型 B 、可以是int 类型 6、下列关于运算符重载的描述中,正确的是( )。 9、对虚函数的调用( ) 。 A 、 定使用动态联编 B 、必须使用动态联编 C 、 定使用静态联编 D 、不一定使用动态联编 10、编译时的多态性可以通过使用( )获 得。 7、下列关于动态联编的描述中,错误的是( )。 8、关于虚函数的描述中,正确的是( )。 A 、虚函数和指针 D 、虚函数和引用

C中用运算符重载实现矩阵运算

走进3D的世界 -- C++中用运算符重载实现矩阵运算 作者:周军 矩阵(Matrix)无处不在,我们的生活中到处都能找到矩阵的身影,然而此处我不想把这个定义放大,我们只讨论线性代数中的矩阵,我们要用它们来完成我们的3D变换。为什么矩阵可以完成3D变换呢?下面,我们就来介绍矩阵是如何变换坐标的: 设空间中有一坐标(x,y,z),如果我们想把它变换成另一坐标(x,’y’,z’),我们可以进行如下操作: = (x’,y’,z’,1) 这就是矩阵的妙用了。它在复杂处理变换的时候表现得尤为突出。假设我们想要把一个物体先沿z轴旋转角thetaZ,再沿x轴旋转角thetaX,我们可以进行如下操作(pseudo-code): obj*=rotX(thetaX)*rotZ(thetaZ); 注意:矩阵的乘法是不可逆的,而且我们要按变化顺序的逆序进行乘法,具体推导见计算几何相关书籍。 下面,我们进入正题:如何再C++中用重载运算符的方法来进行矩阵运算以完成线性变换呢?我们需要变换坐标,所以很自然地,我们需要一个向量(Vector)类;同时我们要进行

为直观、人性化,我选用了运算符重载这以技巧而不是简单地调用函数,下面请看我的具体实现:

以上便是CVector类的具体实现,我想对C++和线性代数有所了解的读者都能很清楚地理解这段代码,在次不累述。 上述代码的成员函数实在类外定义的,如果读者在实践中为了提高速度可以把这些成员函数定义在类内以起到内联函数的作用,可以省去参数压栈、出栈时的时间。 下面是CMatrix类的具体实现:

是不是也很好理解呢?哈哈,这就是用运算符重载的好处。不过这种方法也确实有它的不足,而且这个不足在游戏编程中是致命的,那就是效率不高,这也正是为什么Microsoft 在DirectX中也使用难看的一般函数调用来完成矩阵运算的原因。影响速度的主要原因是在使用运算符+、-、*、/等时,程序会在每次运算时创建临时对象再将临时对象返回,对于重复多次的矩阵运算来说,这无疑成为了一笔庞大的额外开销(好在现在的计算机的处理速度还算快)。但注意:在使用+=、-=、*=、/=时不会有上述问题,因为在使用这些运算符时程序只需要修改第一个对象不需要创建并返回临时对象。所以在能使用+=、-=、*=、/=时尽量不要使用单一的=、-、*、/运算符。 好了,这两个类我们已经封装好了,下面还有什么呢?是的,忘了向大家交代旋转矩阵了:

继承与多态的习题

一:选择题 1. 下面有关析构函数的说法中,不正确的是( ) A.析构函数中不可包含Return语句 B.一个类中只能有一个析构函数 C.用户可定义有参析构函数 D.析构函数在对象被撤销时,被自动调用 2.派生类不可以访问基类的( ) A.Public成员B.Private成员 C.Protected成员D.Protected internel成员 3.有关sealed修饰符,描述正确的是( ) A.密封类可以被继承 B.abstract修饰符可以和sealed修饰符一起使用 C.密封类不能实例化 D.使用sealed修饰符可保证此类不能被派生 4.若想从派生类中访问基类的成员,可以使用( ) A.this关键字B.me关键字 C.base关键字D.override关键字 5.下面有关派生类的描述中,不正确的是( ) A.派生类可以继承基类的构造函数 B.派生类可以隐藏和重载基类的成员 C.派生类不能访问基类的私有成员 D.派生类只能有一个直接基类 6.C#中,继承具有( ),即A类派生B类,B类又派生C类,则C类会继承B类中的成员和A类中的成员。 A.传递性B.多态性C.单继承D.多继承 7.下面有关静态方法的描述中,错误的是( ) A.静态方法属于类,不属于实例 B.静态方法可以直接用类名调用 C.静态方法中,可以定义非静态的局部变量 D.静态方法中,可以访问实例方法 8.下面关于运算符重载的描述中,错误的是( ) A.重载的运算符仍然保持其原来的操作数个数、优先级和结合性不变 B.可以重载双目运算符,不可以重载单目运算符 C.运算符重载函数必须是public的 D.运算符重载函数必须是static的 9.下面对派生类和基类的关系的描述中,不正确的是( ) A.派生类的方法可以和基类的方法同名 B.派生类是对基类的进一步扩充 C.派生类也可作另一个派生类的基类 D.派生类继承基类的公有、保护和私有成员 10.下面关于虚方法的描述中,正确的是() A.虚方法可以实现静态联编 B.在一个程序中,不能有同名的虚方法 C.虚方法必须是类的静态成员

c++运算符重载习题

Task8-1 /* 1. 定义一个复数类Complex,重载运算符“+”,使之能用于复数的加法运算。将运算符函数重载为非成员、非友元的普通函数。编写程序,求两个复数之和*/ #include using namespace std; class Complex { public: Complex(){real=0;imag=0;} Complex(double r,double i){real=r;imag=i;} void display(); double real; double imag; }; void Complex::display() { cout<<"("<

相关主题
相关文档
最新文档