文档库 最新最全的文档下载
当前位置:文档库 › 11多态性与虚函数

11多态性与虚函数

11多态性与虚函数
11多态性与虚函数

第10章多态性与虚函数

【内容提要】

多态性的概念;

函数和运算符的重载;

虚函数和抽象类。

【重点与难点】

10.1 多态性的概念

在面向对象的概念中,多态性是指不同对象接收到相同消息时,根据对象类的不同产生不同的动作。

由静态联编支持的多态性称为编译时的多态性或静态多态性,也就是说,确定同名操作的具体操作对象的过程是在编译过程中完成的。C++用函数重载和运算符重载来实现编译时的多态性。

由动态联编支持的多态性称为运行时的多态性活动太多态性,也就是说,确定同名操作的具体操作对象的过程是在运行过程中完成的。C++用继承和虚函数来实现运行时的多态性。

10.2 函数和运算符的重载

10.2.1 函数重载

面向对象程序设计中,函数的重载表现为两种情况:第一种是参数个数或类型有所差别的重载,第二种是函数的参数完全相同但属于不同的类。

10.2.2 运算符重载

C++预定义的运算符只是对基本数据类型进行操作,而对于自定义的数据类型比如类,却没有类似的操作。为了实现对自定义类型的操作,就必须自己编写程序来说明某个运算符作用在这些数据类型上时,应该完成怎样的操作,这就要引入运算符重载的概念。

运算符的重载形式有两种,一种是重载为类的成员函数,一种是重载为类的友元函数。

成员运算符函数的定义:

在类内声明的一般形式为:

<返回类型> operator<运算符>(参数表);

在类外定义的一般形式为:

<返回类型> <类名∷> operator<运算符>(参数表)

{

函数体

}

其中,operator是定义运算符重载函数的关键字;运算符是要重载的运算符的名称;参数表给出重载运算符所需要的参数和类型。

将重载的运算符函数定义为类的友元函数,称为友元运算符函数。友元运算符函数不

友员运算符函数的定义:

在类内声明的一般形式为:

friend<返回类型> operator<运算符>(参数表);

在类外定义的一般形式为:

<返回类型> operator<运算符>(参数表)

{

函数体

}

其中,friend是声明友元函数的关键字,operator是定义运算符重载函数的关键字;运

算符是要重载的运算符的名称;参数表给出重载运算符所需要的参数和类型。

几种典型运算符的重载

①加法运算符“+”的重载

②“++”和“--”的重载

③赋值运算符“=”的重载

④函数调用运算符“()”的重载

⑤下标运算符“[ ]”的重载

10.3 虚函数和抽象类

虚函数是重载的另一种形式,实现的是动态的重载,即函数调用与函数体之间的联系是在运行时才建立,也就是动态联编。

10.3.1 虚函数的定义和使用

虚函数的定义是在基类中进行的,即把基类中需要定义为虚函数的成员函数声明为virtual。当基类中的某个成员函数被声明为虚函数后,它就可以在派生类中被重新定义。在派生类中重新定义时,其函数原型,包括返回类型、函数名、参数个数和类型、参数的顺序都必须与基类中的原型完全一致。

虚函数定义的一般形式为:

virtual<函数类型><函数名>(参数表)

{

函数体

}

使用虚函数时应注意如下问题:

①虚函数的声明只能出现在类声明的函数原型的声明中,不能出现在函数体实现的时候,

而且,基类中只有保护成员或公有成员才能被声明为虚函数。

②在派生类中重新定义虚函数时,关键字virtual可以写也可不写,但在容易引起混乱时,

应写上该关键字。

③动态联编只能通过成员函数来调用或通过指针、引用来访问虚函数,如果用对象名的形

式来访问虚函数,将采用静态联编。

④虚函数必须是所在类的成员函数,不能是友元函数或静态成员函数。但可以在另一个类

中被声明为友元函数。

⑤构造函数不能声明为虚函数,析构函数可以声明为虚函数。

⑥由于内联函数不能在运行中动态确定其外治,所以它不能声明为虚函数。

10.3.2 纯虚函数和抽象类

抽象类是一种特殊的类,它为一族类提供统一的操作界面,建立抽象类就是为了通过它多态地使用其中的成员函数。抽象类是带有纯虚函数的类。

一个抽象类至少带有一个纯虚函数。纯虚函数是在一个基类中说明的虚函数,它在该基类中没有具体的操作内容,要求各派生类在重新定义时根据自己的需要定义实际的操作内容。纯虚函数的一般定义形式为:

virtual<函数类型><函数名>(参数表)=0;

纯虚函数与普通虚函数的定义的不同在于书写形式上加了“=0”,说明在基类中不用定义该函数的函数体,它的函数体由派生类定义。

如果一个类中至少有一个纯虚函数,这个类就成为抽象类。它的主要作用是为一个族类提供统一的公共接口,以有效地发挥多态的特性。使用时应注意以下问题:

①抽象类只能用作其它类的基类,不能建立抽象类的对象。因为它的纯虚函数没有定义功

能。

②抽象类不能用作参数类型、函数的返回类型或显式转换的类型。

③可以声明抽象类的指针和引用,通过它们,可以指向并访问派生类对象,从而访问派生

类的成员。

④若抽象类的派生类中没有给出所有纯虚函数的函数体,这个派生类仍是一个抽象类。若

抽象类的派生类中给出了所有纯虚函数的函数体,这个派生类不再是一个抽象类,可以声明自己的对象。

【典型例题】

例题1.下面关于虚函数和函数重载的叙述不正确的是()。

(a)虚函数不是类的成员函数

(b)虚函数实现了C++的多态性

(c)函数重载允许非成员函数,而虚函数则不行

(d)函数重载的调用根据参数的个数、序列来确定,而虚函数依据对象确定

解答:

函数重载和虚函数是C++中实现多态性的两种手段,但是它们的实现机制是不一样的;函数重载依据调用时的参数进行区分,而虚函数则根据对象实际的指向确定调用的版本。答案为:a。

例题2.()是一个在基类中说明的虚函数,它在该基类中没有定义,但要求任何派生类都必须定义自己的版本。

(a)纯虚函数(b)虚析构函数(c)虚构造函数(d)静态成员函数

解答:

抽象类中的纯虚函数没有具体的定义,需要在抽象类的派生类中定义。因此,纯虚函数是一个在基类中说明的虚函数,它在该基类中没有定义,但要求任何派生类都必须定义自己的版本。答案为:a

例题3.实现运行时的多态性要使用()。

(a)构造函数(b)析构函数(c)重载函数(d)虚函数

解答:

动态联编要在程序运行时才能确定调用哪个函数。虚函数是实现动态联编的必要条件之一,没有虚函数一定不能实现动态联编。答案为:d。

例题4.关于虚函数的描述中,()是正确的。

(a)派生类的虚函数与基类的虚函数具有不同的参数个数和类型

(b)基类中说明勒虚函数后,派生类中其对应的函数一定要说明为虚函数

(c)虚函数是一个成员函数

(d)虚函数是一个static类型的成员函数

解答:

为实现某种功能而假设的函数称为虚函数。虚函数是用关键字virtual进行说明。虚函数是动态联编的基础。虚函数只能是类中的一个成员函数,但不能是静态成员;派生类的虚函数与基类的虚函数具有相同的参数个数和类型,当派生类的虚函数与基类中的对应的虚函数的参数不同时,派生类的虚函数将丢失虚特性,变为重载函数;对于基类中的虚函数,在派生类中自然是虚函数,可不必说明。答案为:c。

例题5.下面的程序中,有错误的语句是__________。

class A //①

{

public: //②

A()

{

func(); //③

}

virtual void func()=0; //④

};

解答:

在成员函数内可以调用纯虚函数,但在构造函数或析构函数内调用一个纯虚函数将导致程序运行错误,因为没有为纯虚函数定义代码。答案为:③

例题6.运行下列程序的结果为__________________。

#include

class base

public:

void display1(){cout<<"base::display1()"<

virtual void display2(){cout<<"base::display2()"<

};

class derived:public base

{

public:

void display1(){cout<<"derived::display1()"<

void display2(){cout<<"derived::display2()"<

};

void main()

{

base * pbase;

derived d;

pbase=&d;

pbase->display1 ();

pbase->display2();

}

解答:

本题主要考查有关多态性的相关知识。在基类base中,定义了一个函数display1()和虚函数display2();在派生类derived中,重写了函数display1(),而且重新定义的虚函数display2()。由于基类指针pbase指向的是派生类的一个对象,因而会调用派生类的display2()版本,但是对于一般的成员函数display1(),仍然遵循一般的调用规则,只调用基类的display1()版本。本题答案为:

base::display1()

derived::display2()

例题7.下面的程序的输出结果为an animal a person an animal a person,请将程序补充完整。

#include

class animal{

public:

______①_____ void speak(){cout<<"An animal"<<" ";}

};

class person:public animal{

public:

void speak(){cout<<"a person"<<" ";}

};

void main()

{

animal a,_______②_______;

person p;

a.speak();

p.speak();

pa=&a;

pa->speak();

________③_______;

pa->speak();

}

解答:

本题主要考查对多态性的理解与应用。本题通过虚函数实现多态性,所以在基类中应定义虚函数;为了实现多态性,必须定义基类的指针,然后将它指向各个派生类的对象。本题答案为:①virtual、②*pa、③pa=&p

【习题】

一、选择题

1.在C++中,用于实现运行时多态性的是()。

A)内联函数

B)重载函数

C)模板函数

D)虚函数

2.如果一个类至少有一个纯虚函数,那么就称该类为()。

(a)抽象类(b)派生类(c)虚基类(d)以上都不对

3.为了区分一元运算符的前缀和后缀运算,在后缀运算符进行重载时,额外添加一个参

数,其类型是()。

(a)void (b)char (c)int (d)float

4.下面关于运算符重载的说法中,错误的是()。

(a)可以对C++所有运算符进行重载

(b)运算符重载保持固有的结合性和优先级顺序

(c)运算符重载不能改变操作数的个数

(d)在运算符函数中,不能使用缺省的参数值

5.下列关于抽象类的说明中不正确的是()。

(a)含有纯虚函数的类称为抽象类

(b)抽象类不能被实例化,但可声明抽象类的指针变量

(c)抽象类的派生类可以实例化

(d)纯虚函数可以被继承

6.运行下列程序的输出结果为()。

#include

class base

{

public:

void fun1(){cout<<"base"<

virtual void fun2(){cout<<"base"<

};

class derived:public base

{

public:

void fun1(){cout<<"derived"<

void fun2(){cout<<"derived"<

};

void f(base &b){b.fun1();b.fun2();}

int main()

{

derived obj;

f(obj);

return 0;

}

(a)base (b)base (c)derived (d)derived

Base derived base derived

7.运行下列程序结果为()。

#include

class complex

{

double re,im;

public:

complex(double r,double i):re(r),im(i){}

double real() const{return re;}

double image() const{return im;}

complex& operator+=(complex a)

{

re+=a.re ;

im+=a.im ;

return *this;

}

};

ostream &operator<<(ostream&s,const complex& z)

{

return s<<'('<

}

int main()

{

complex x(1,-2),y(2,3);

cout<<(x+=y)<

return 0;

}

(a) (1,-2) (b) (2,3) (c) (3,5) (d) (3,1)

二、填空题

1.多数运算符既能作为类的成员函数重载,也能作为类的非成员函数重载,但[ ]运算符

只能作为类的____________函数重载。

2.下列程序的输出结果为2,请将程序补充完整。

#include

using namespace std;

class Base

{

public:

_____________ void fun( ){ cout<<1; }

};

class Derived:public Base

{

public:

void fun( ) { cout<<2; }

};

int main( )

{

Base *p= new Derived;

p->fun( );

delete p;

return 0;

}

3.运行下列程序结果为_________________。

#include

class one

{

public:

virtual void f(){cout<<"1";}

};

class two:public one

{

public:

two(){cout<<"2";}

};

class three:public two

{

public:

virtual void f(){two::f();cout<<"3"; }

};

int main()

{

one aa,*p;

two bb;

three cc;

p=&cc;

p->f();

return 0;

}

4.运行下列程序结果为_____________。

#include

using namespace std;

class A{

public:

virtual void funcl(){cout<<"A1";}

void func2(){cout<<"A2";}

};

class B: public A{

public:

void func1(){cout<<"B1";}

void func2(){cout<<"B2";}

};

int main(){

A *p=new B;

p->funcl();

p->func2();

return 0;

}

5.下面的程序通过重载运算符“+”实现了两个一维数组对应元素的相加。请将程序补充

完整。

#include

class Arr

{

int x[20];

public:

Arr(){for(int i=0;i<20;i++) x[i]=0;}

Arr(int *p)

{for(int i=0;i<20;i++)x[i]=*p++;}

Arr operator+(Arr a)

{

Arr t;

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

t.x[i]=________ ①___________;

return _________②________;

}

Arr operator+=(Arr a)

{

for(int i=0;i<20;i++)x[i]=______③_______;

return ______④________;

}

void show()

{

for(int i=0;i<20;i++)cout<

cout<

}

};

void main()

{

int array[20];

for(int i=0;i<20;i++) array[i]=i;

Arr a1(array),a2(array),a3;

a3=a1+a2;a3.show ();

a1+=a3;a1.show();

}

6.运行下列程序,分别输入”tom”、”m”、”23”、”321456”输出结果为___________________。#include

#include

class Employee

{

public:

Employee(void) {};

Employee(char *name, char sex, int age, char *phone)

{

strcpy(Employee::name, name);

Employee::sex = sex;

Employee::age = age;

strcpy(Employee::phone, phone);

};

friend ostream &operator<<(ostream &cout, Employee emp);

friend istream &operator>>(istream &stream, Employee &emp);

private:

char name[256];

char phone[64];

int age;

char sex;

};

ostream &operator<<(ostream &cout, Employee emp)

{

cout << "Name: " << https://www.wendangku.net/doc/4b7815113.html, << ";Sex: " << emp.sex;

cout << ";Age: " << emp.age << ";Phone: " << emp.phone << endl;

return cout;

}

istream &operator>>(istream &stream, Employee &emp)

{

cout << "Enter Name: ";

stream >> https://www.wendangku.net/doc/4b7815113.html,;

cout << "Enter Sex: ";

stream >> emp.sex;

cout << "Enter Age: ";

stream >> emp.age;

cout << "Enter Phone: ";

stream >> emp.phone;

return stream;

}

void main(void)

{

Employee worker;

cin >> worker;

cout << worker ;

}

7.运行下列程序结果为_______________________。

#include

class sample {

public:

int i;

sample *operator->(void) {return this;}

};

void main(void)

{

sample obj;

obj->i = 10;

cout << obj.i << " " << obj->i;

}

8.运行下列程序结果为_________________________。

#include

#include

class Base

{

public:

virtual int add(int a, int b) { return(a + b); };

virtual int sub(int a, int b) { return(a - b); };

virtual int mult(int a, int b) { return(a * b); };

};

class ShowMath : public Base

{

virtual int mult(int a, int b)

{

cout << a * b << endl;

return(a * b); };

};

class PositiveSubt : public Base

{

virtual int sub(int a, int b) { return(abs(a - b)); };

};

void main(void)

{

Base *poly = new ShowMath;

cout << poly->add(562, 531) << ' ' << poly->sub(1500, 407) <<' '; poly->mult(1093, 1);

poly = new PositiveSubt;

cout << poly->add(892, 201) << ' ' << poly->sub(0, 1093) << ' '; cout << poly->mult(1, 1093);

}

三、编程题

1.下面的shape类是一个表示形状的抽象类,area()为求图形面积的函数,total()是一个求不同形状的图形面积总和的函数。请从shape类派生三角形类(triangle)和矩形类(rectangle),并给出具体的求面积函数。

class shape

{

public:

virtual float area()=0;

};

float total(shape *s[],int n)

{

float sum=0.0;

for(int i=0;i

sum+=s[i]->area();

return sum;

}

2.编写程序,定义一个描述三维空间坐标点的类,用成员函数重载“+”运算符以实现两个三维坐标的相加,用友元函数重载前置“++”运算符以实现三维坐标的加一操作。

【参考答案】

一、选择题

1. d

2. a

3. c

4. a

5. c

6. b

7. d

二、填空题

1.成员

2.virtual

3.2213

4.A1A2

5.①x[i]+a.x[i] 、②t 、③x[i]+a.x[i] 、④*this

https://www.wendangku.net/doc/4b7815113.html,:tom;Sex:m;Age:23;Phone:321456

7.10 10

8.1093 1093 1093

1093 1093 1093

三、编程题

1.参考程序如下:

#include

#include

class shape

{

public:

virtual float area()=0;

};

class rectangle:public shape

{

float width,height;

public:

rectangle(float w,float h){width=w;height=h;}

void show()

{

cout<<"width:"<

cout<<"area:"<

}

float area(){return width*height;}

};

class triangle:public shape

{

float a,b,c;

public:

triangle(float aa,float bb,float cc)

{a=aa;b=bb;c=cc;}

float show()

{

cout<<"a:"<

cout<<"area:"<

}

float area()

{

float s=(a+b+c)/2;

return sqrt(s*(s-a)*(s-b)*(s-c));

}

};

float total(shape *s[],int n)

{

float sum=0.0;

for(int i=0;i

sum+=s[i]->area();

return sum;

}

void main()

{

float w,h,aa,bb,cc;

cout<<"请输入三角形的三条边:"<

cin>>aa>>bb>>cc;

triangle t(aa,bb,cc);

cout<<"请输入矩形的长和宽:"<

cin>>w>>h;

rectangle r(w,h);

shape *p[2];

p[0]=&t;

p[1]=&r;

cout<<"两个图形面积的和为:"<

}

2.参考程序如下:

#include

class threedime

{

float x,y,z;

public:

threedime(float a=0,float b=0,float c=0){x=a;y=b;z=c;}

void show(){cout<<"x:"<

friend threedime operator++(threedime& c);

};

threedime threedime::operator+(threedime c)

{

threedime t=*this;

t.x+=c.x;

t.y+=c.y;

t.z+=c.z;

return t;

}

threedime operator++(threedime& c)

{

c.x++;

c.y++;

c.z++;

return c;

}

void main()

{

threedime td1(1,2,3),td2(1,1,1),td3,td4;

td1.show();td2.show();

td3=++td1;td4=td1+td2;

td3.show();td4.show();

}

实验6 多态性(一)

福建农林大学实验报告 实验6 多态性(一) 一、实验目的和要求 (1)掌握虚函数的定义与使用方法,进一步理解多态性的概念和分类。 (2)了解纯虚函数和抽象类的使用方法。 二、实验内容和原理 1、分析并调试下列程序,回答以下问题:(1)指出抽象类(2)指出虚函数,并说明它的作用(3)每个类的作用是什么?整个程序的作用是什么? 2、使用虚函数编写程序求球体、圆柱体和圆锥的体积,由于球体、圆柱体和圆锥都可以看做由圆继 承而来,所以可以定义圆类作为基类。在圆类中定义数据成员半径和一个求体积的虚函数。由圆类 派生出球体类、圆柱体类和圆锥类,在派生类中对圆类中的虚函数重新定义。编写一个外部函数求 各类形状的总体积。最后在main()函数中构造若干形状,并求它们的体积和。

三、实验环境 1. 硬件:PC机; 2. 软件:Windows操作系统、Visual C++ 6.0 四、算法描述及实验步骤 1、算法描述及步骤如下: (1)根据题目要求编写好程序代码并在VC环境下输入源程序。 (2)检查程序有无错误(包括语法错误和逻辑错误),有则改之。 (3)编译和连接,仔细分析编译信息,如有错误应找出原因并改正之。本题改正后的代码如下: #include const double PI=3.1415; class Shap { public:virtual double Area()=0; }; class Triangle:public Shap { public:Triangle(double h,double w) { H=h; W=w; } double Area() { return 0.5*H*W; } private:double H,W; }; class Circle:public Shap { public:Circle(double r) { R=r; } double Area() { return PI*R*R; } private:double R; }; double Total(Shap*s[],int n) { double sum=0; for(int i=0;i

实验8 多态性与虚函数

实验八多态性与虚函数 一、实验目的和要求 1.了解多态的概念; 2.了解虚函数的作用及使用方法; 3.了解静态关联和动态关联的概念和用法; 4.了解纯虚函数和抽象类的概念和用法 二、实验内容和结果 1.阅读下面的程序 1.1请写出程序的执行结果,并在上机时对照理解 class Vehicle {public: void run() const { cout << "run a vehicle. "<

airplane.run(); cout<<"(b) 用指向基类的指针访问成员函数: "<run(); vp=&airplane; vp‐>run(); } 1.2 如果将Vehicle 类的定义修改为虚函数,其余不变,请写出程序的执行结果,并在上机时对照理解 class Vehicle {public: virtual void run() const { cout << "run a vehicle. "<

多态性和虚函数

多态性和虚函数

Problem A: C++习题抽象基类Description 编写一个程序,声明抽象基类Shape,由它派生出3个派生类:Circle(圆形)、Rectangle(矩形)、Triangle(三角形),用一个函数printArea分别输出以上三者的面积(结果保留两位小数),3个图形的数据在定义对象时给定。 Input 圆的半径 矩形的边长 三角形的底与高 Output 圆的面积 矩形的面积 三角形的面积 Sample Input 12.6 4.5 8.4 4.5 8.4 Sample Output area of circle = 498.76 area of rectangle = 37.80 area of triangle = 18.90 #include #include using namespace std; class Shape { public:

virtual double area()const=0; }; class Circle:public Shape { public: Circle(double r):radius(r) {} virtual double area() const { return 3.14159*radius*radius; }; protected: double radius; }; class Rectangle:public Shape { public: Rectangle(double w,double h):width(w),height(h) {} virtual double area() const { return width*height; }

c++多态性与虚函数习题

作业题 一、写出下列程序运行结果 1.#include using namespace std; class A { public: virtual void func( ) {cout<<”func in class A”< using namespace std; class A{ public: virtual ~A( ){ cout<<”A::~A( ) called “<

}; void fun(A *a) { delete a; } int main( ) { A *a=new B(10); fun(a); } 二、程序设计题 1有一个交通工具类vehicle,将它作为基类派生小车类car、卡车类truck和轮船类boat,定义这些类并定义一个虚函数用来显示各类信息。 5.2定义一个shape抽象类,派生出Rectangle类和Circle类,计算各派生类对象的面积Area( )。 5.5某学校对教师每月工资的计算公式如下:固定工资+课时补贴。教授的固定工资为5000元,每个课时补贴50元;副教授的固定工资为3000元,每个课时补贴30元;讲师的固定工资为2000元,每个课时补贴20元。给出教师抽象类及主函数,补充编写程序求若干教师的月工资。 #include using namespace std; class Teacher{ protected: double salary; int workhours; public: Teacher(int wh=0){workhours=wh;} virtual void cal_salary()=0; void print(){cout<cal_salary(); prof.print(); Vice_Prof vice_prof(250); pt=&vice_prof; pt->cal_salary(); vice_prof.print(); Lecture lecture(100); pt=&lecture; pt->cal_salary(); lecture.print (); return 0; }

实验6多态性与虚函数

[实验目的] 1、了解多态性的概念; 2、了解虚函数的用途及使用方法; 3、了解纯虚函数和抽象类的概念和用法。 [实验要求] 给出以下各实验内容的源程序代码,并把编译、运行过程中出现的问题以及解决方法填入实验报告中,按时上交。 [实验学时] 2学时。 [实验内容] 1、写一个程序,定义抽象基类Shape,由它派生出3个派生类:Circle(圆形)、Square(正方形)、Rectangle(矩形)。利用指针、虚函数printArea()分别输出以上三者的面积,3个图形的数据在定义对象时给定。 [源程序] #include using namespace std; class Shape { public: virtual float area()const=0; virtual void display()const=0; }; class Circle:public Shape { public: Circle(double a):r(a){} virtual float area()const{return 3.14*r*r;} virtual void display()const { cout<<"圆面积"<

class Rectangle:public Shape { public: Rectangle(double a,double b):l(a),w(b){} virtual float area()const{return l*w;} virtual void display()const { cout<<"矩形面积"<display(); m=m+p[i]->area(); }

实验三虚函数与多态纯虚函数(完全版)

实验三虚函数与多态、纯虚函数 一.实验目的 1. 在掌握继承与派生关系的基础上,进一步理解虚函数与多态性的关系,实现运行时的多态。 2. 学会定义和使用纯虚函数 二、实验内容 1.范例:了解"单接口,多方法"的概念。现有称为figure的基类,存放了各二维对象(三角形、矩形和圆形三个类)的各维数据,set_dim()设置数据,是标准成员函数。 show_area()为虚函数,因为计算各对象的面积的方法是不同的。 【程序】 #include < iostream > using namespace std; class figure{ protected: double x,y;

public: void set_dim(double i,double j=0) { x=i; y=j; } virtual void show_area() { cout<<"No area computation defined for this class.\n"; } }; class triangle:public figure{ public: void show_area() { cout<<"Triangle with height "<< x<<" and base "<< y<<" has an area of "<< x*0.5*y<< endl; } }; class square:public figure{ public:

void show_area() { cout<<"Square with dimensions "<< x<<" and "<< y<<" has an area of "<< x*y<< endl; } }; class circle:public figure{ public: void show_area() { cout<<"Circle with radius "<< x<<" has an area of "<<3.14159*x*x<< endl; } }; int main(){ figure *p; triangle t; square s;

实验六 多态性和虚函数

实验六多态性和虚函数 一、实验目的 1、了解多态性的概念。 2、了解虚函数的作用及其使用方法。 3、了解静态关联和动态关联的概念和用法。 4、了解纯虚函数和抽象类的概念和用法。 二、实验要求 1、分析程序运行结果,掌握虚函数的使用。 程序一: #include class ONE { public: virtual void f(){cout<<"l"<f(); } 程序二: #include class Base { public: virtual void fn() { cout <<"In Base Class\n";} }; class SubClass :public Base { public: virtual void fn(){ cout <<"In Sub Class\n"; } }; void main()

{ Base bc,*p; SubClass sc; p=&bc; p->fn(); p=≻ p->fn(); } 2、实现一个类A,在A中有两个私有的整型变量a和b,定义构造函数对a和b进行初始化,并实现成员函数geta()取得a的值和getb()取b的值。实现类B从A继承,覆盖geta(),使其返回a的2倍。主函数中声明类B对象,调用类B中的geta()并将结果输出。 3、声明抽象基类Shape,由它派生出3个派生类:Cirle(圆形)、Rectangle(矩形)、Triangle (三角形),用一个函数printArea分别输出以上三者的面积,3个图形的数据在定义对象是给定。

C++实验多态性实验报告

贵州大学实验报告 学院:电子信息学院专业:通信工程班级: 姓名学号实验组5实验时间指导教师成绩 实验项目名称多态性 实 验通过让学生进行实验,使其对于动态多态性有一个较为深入的了解和熟悉。最终可以目熟练使用。 的 实 1.编写 4 个重载函数 Double( x),返回值为输入参数的两倍;参数类型分别为int 、验long 、float 、 double ,返回值类型与参数类型一样。 2.请编写一个抽象类Shape,在此基础上派生出类Rectangle和Circle,二者都有 要 计算对象面积的函数GetArea ()和计算周长函数GetPerim ()。 求3.对类 Point 重载 ++(自增)、 -- (自减)运算符。 实 验Visual C++的编译环境下,独立完成实验要求的内容,独立完成编写、编译以及运行 原的过程 理 实 验 安装了 Visual C++ 的 PC机器 仪 器 实 验 按照实验要求的内容逐一完成实验的要求。顺序是编写、编译、运行。 步 骤

实 1. 编写 4 个重载函数 Double(x),返回值为输入参数的两倍;参数类型分别为int、 验 long 、 float 、 double ,返回值类型与参数类型一样。 2. 请编写一个抽象类Shape,在此基础上派生出类Rectangle 和 Circle,二者都有计 内算对象面积的函数GetArea ()和计算周长函数GetPerim ()。容 3. 对类 Point 重载 ++(自增)、 -- (自减)运算符。 1、代码如下: #include using namespace std; int Double(int x); long Double(long x); float Double(float x); double Double(double x); int main() { int myInt = 6500; cout< #define PI 3.1415926; using namespace std; class Shape // 抽象类的定义 { public: virtual double GetArea()= 0; //纯虚函数

实验五 虚函数与多态性

实验三继承与多态性 一、实验目的与要求 1、掌握继承、基类和派生类的概念。 2、掌握初始化基类成员的方法。 3、掌握派生类对基类的继承。 4、学习虚函数和纯虚函数的定义与使用方式。 5、理解抽象类的概念,学习如何用指针指向其他的派生类,实现多态性。 6、掌握抽象类的定义与使用方式,并注意指针的用法。 7、学习如何使用虚函数、纯虚函数、抽象类和实现类的多态性。 二、实验设备与平台 实验设备要求每个学生一台电脑,其中运行环境为VC++ 6.0系统或新版。 三、实验内容与步骤 实验:编写一个人员信息管理系统。这个系统的功能是:交互式地实现校园人员信息的录入与显示。 分析: 学校里,主要有四类人员:大学本科学生、教师、研究生和助教。 大学本科生每周有固定的学时数。教师除了固定的学时数外,还有每周的教学时数。研究生除了固定的学时数外,每周还可以自由做一定的研究。助教除了上课外,还要做研究和一定的教学工作。 人员的基本信息包括姓名、编号、性别、身份证号、总学时数、以及每周固定学时数。各个人员之间的关系:people类派生出student类和teacher类,student类派生出graduate 类,graduate类和teacher类派生出TA类。 以下给出部分程序: #include using namespace std; class people { public: //添加程序 private: }; class student: virtual public people {

public: //添加程序 private: }; class teacher: virtual public people { public: //添加程序 private: }; class graduate: virtual public student { public: //添加程序 private: }; class TA: public graduate, public teacher { public: //添加程序 private: }; void main() { //添加程序 }

多态性和虚函数 实验报告

淮海工学院计算机科学系实验报告书 课程名:《 C++程序设计(二)》 题目:多态性和虚函数 班级: 学号: 姓名:

1、实验内容或题目 (1)声明二维坐标类作为基类派生圆的类,把派生类圆作为基类,派生圆柱体类。其中,基类二维坐标类有成员数据:x、y坐标值;有成员函数:构造函数实现对基类成员数据的初始化、输出的成员函数,要求输出坐标位置。派生类圆类有新增成员数据:半径(R);有成员函数:构造函数实现对成员数据的初始化、计算圆面积的成员函数、输出半径的成员函数。派生圆柱体类新增数据有高(H);新增成员函数有:构造函数、计算圆柱体体积的函数和输出所有成员的函数。请完成程序代码的编写、调试。 (2)教材393页7-8题。 (3)教材416页1、4、5题。 2、实验目的与要求 (1)理解继承与派生的概念 (2)掌握通过继承派生出一个新的类的方法 (3)了解多态性的概念 (4)了解虚函数的作用与使用方法 3、实验步骤与源程序 ⑴实验步骤 先定义一个基类point,及其成员函数,然后以public的继承方式定义子类circle,再定义一个派生类cylinder,最后在main主函数中定义类对象,调用函数实现其功能。 先定义一个基类A及其重载的构造函数,然后以Public派生出子类B,再定义其构造函数,最后在main主函数中定义类对象,调用成员函数实现其功能。 ⑵源代码 1.#include class Point { public: Point(float=0,float=0); void setPoint(float,float); float getX() const {return x;}

实验8_继承和多态

实验08:继承与多态 实验学时:6 实验类型:验证、设计 实验要求:必修 一、实验目的 1.理解继承的概念,了解面向对象设计中继承和多态的合理性; 2.掌握派生类的构造与析构; 3.掌握在对象中使用类层次和继承思想进行设计、实现和测试; 4.区别运行时的多态性的实现,理解重载与同名覆盖的差异; 5.理解虚函数与多态性; 6.实现运行时多态性的程序设计。 二、实验内容 1.Difine a class called PartFileledArrayWMax that is a derived class of the class PartFilledArray. The class PartFilledArrayWMax has one additional member variable named max_value that holds the maximum value stored in the array. Define a member accessor function named get_max that returns the maximum value stored in the array. Redefine the member function add_value and define two constructors, one of which has an int argument for the maximum number of entries in the array. Also define a copy constructor, an overloaded assignment operator, and a destructor. (A real class would have more member functions, but these will do for an exercise.) 2.某公司雇员(employee)包括经理(Manager)、技术人员(Technician)和销售员(Saleman)。开发部经理(developermanager)既是经理也是技术人员,销售部经理(salesmanager)既是经理也是销售员。 以employee类为虚基类,派生出manager、technician和saleman类,再进一步派生出developermanager和salesmanager类。 Employee类的属性包括姓名、职工号、工资级别、月薪(实发基本工资加业绩工资);操作包括月薪计算函数pay(),该函数要求输入请假天数,扣除应扣工

c++多态性与虚函数习题答案

多态性与虚函数 1.概念填空题 1.1 C++支持两种多态性,分别是编译时和运行时。 1.2在编译时就确定的函数调用称为静态联编,它通过使用函数重载,模板等实现。 1.3在运行时才确定的函数调用称为动态联编,它通过虚函数来实现。 1.4虚函数的声明方法是在函数原型前加上关键字virtual。在基类中含有虚函数,在派生类中的函数没有显式写出virtual关键字,系统依据以下规则判断派生类的这个函数是否是虚函数:该函数是否和基类的虚函数同名;是否与基类的虚函数参数个数相同、类型;是否与基类的虚函数相同返回类型。如果满足上述3个条件,派生类的函数就是虚函数。并且该函数覆盖基类的虚函数。 1.5 纯虚函数是一种特别的虚函数,它没有函数的函数体部分,也没有为函数的功能提供实现的代码,它的实现版本必须由派生类给出,因此纯虚函数不能是友元函数。拥有纯虚函数的类就是抽象类类,这种类不能实例化。如果纯虚函数没有被重载,则派生类将继承此纯虚函数,即该派生类也是抽象。 3.选择题 3.1在C++中,要实现动态联编,必须使用(D)调用虚函数。 A.类名 B.派生类指针 C.对象名 D.基类指针 3.2下列函数中,不能说明为虚函数的是(C)。 A.私有成员函数 B.公有成员函数 C.构造函数 D.析构函数 3.3在派生类中,重载一个虚函数时,要求函数名、参数的个数、参数的类型、参数的顺序和函数的返回值(A)。 A.相同 B.不同 C.相容 D.部分相同 3.4当一个类的某个函数被说明为virtual时,该函数在该类的所有派生类中(A)。 A.都是虚函数 B.只有被重新说明时才是虚函数 C.只有被重新说明为virtual时才是虚函数 D.都不是虚函数 3.5(C)是一个在基类中说明的虚函数,它在该基类中没有定义,但要求任何派生类都必须定义自己的版本。 A.虚析构函数B.虚构造函数 C.纯虚函数D.静态成员函数 3.6 以下基类中的成员函数,哪个表示纯虚函数(C)。 A.virtual void vf(int);B.void vf(int)=0; C.virtual void vf( )=0;D.virtual void vf(int){ } 3.7下列描述中,(D)是抽象类的特性。 A.可以说明虚函数 B.可以进行构造函数重载 C.可以定义友元函数 D.不能定义其对象 3.8类B是类A的公有派生类,类A和类B中都定义了虚函数func( ),p是一个指向类A对象的指针,则p->A::func( )将(A)。

多态性与虚函数练习

多态性与虚函数练习 1.设计一个评选优秀教师和学生的程序,其类结构如图1所示。当输入一系列教师或学生的记录后,将优秀学生及教师的姓名列出。 图1 类结构 假设运行结果如下所示:#include #include using namespace std; class Base { public: void getname(){ cout<<"姓名:";cin>>name;} void printname() { cout<>num;} int isgood() { return num>90?1:0;} private: int num; }; class Teacher:public Base { public: void getnum() { cout<< "每年发表论文数:";cin>>num;} int isgood(){ return num>3?1:0;} 类Base void getname() void printname() 纯虚函数int ifgood()=0 string name 类student void getnum() int num 纯虚函数ifgood实现:若考试成绩大于90分,则返回1 类teachere void getnum() int num 纯虚函数ifgood实现:若一年发表论文大于3篇,则返回1

实验四 类的多态性与虚函数

实验四类的多态性与虚函数 (实验课时:2 实验性质:设计) 实验名称: 类的多态性与虚函数 实验目的: (1)了解多态性的概念; (2)了解虚函数的作用和使用方法; (3)了解纯虚函数和抽象类的概念和用法。 实验设备:(1)硬件:个人微机(配置不低于:CPU为P4,主频1.6G,内存256MB,硬盘40GB); (2)软件:操作系统为WindowsXP(或2000、server2003等),工具软件为Visual C++6.0。 实验内容: 事先编好程序,上机调试和运行程序,分析结果。 (1)编程:定义抽象基类Shape(图形)。 Shape类有一个公共的纯虚函数Area,用于派生类求图形的面积。 (2)由Shape派生出3个派生类:Circle(圆形)、Rectangle(矩形)、Triangle(三角形),用一个函数PrintArea分别输出以上三者的面积,3个图形的数据在定义对象时给定。 在主程序中测试这些类的PrintArea函数。 (3)在类Circle基础上再派生一个圆柱体Cylinder,重载Area函数求圆柱体的体积。然后,编写主程序采用静态多态性和动态多态性分别测试Area函数。 (4)在类Circle中定义一个析构函数,让它输出一行信息“This is Cicle Destruction。”,在类Cylinder中定义一个析构函数,让它输出一行信息“This is Cylinder Destruction。”。 在主程序中用指向基类Circle类的指针动态生成Cylinder类对象,然后用delete 语句释放该对象,测试看看运行结果如何。再修改Circle的析构函数为虚函数,测试看看运行结果如何。 (5)运行上述程序,并分析结果。 实验要求: (1)掌握多态性的概念; (2)掌握虚函数的作用和使用方法; (3)掌握纯虚函数和抽象类的概念和用法; (4)程序格式规范,程序运行正确; (5)认真书写实验报告,如实填写各项实验内容。 实验步骤: (1)启动Visual C++6.0开发环境; (2)创建一个项目; (3)建立C++源程序文件; (4)编辑C++源程序文件内容; (5)建立并运行可执行程序,并分析结果; (6)关闭工作空间。 思考题:虚函数的作用是什么?、

实验6多态性与虚函数

序号 实验6多态性与虚函数 [实验目的] ---------------------- 1、了解多态性的概念; 2、了解虚函数的用途及使用方法; 3、了解纯虚函数和抽象类的概念和用法。 [实验要求] 给出以下各实验内容的源程序代码,并把编译、运行过程中出现的问题 以及解决方法填入实验报告中,按时上交。 [实验学时] 2学时。 [实验内容] 1、写一个程序,定义抽象基类Shape由它派生出3个派生类:Circle(圆形)、Square正方形)、Rectangle矩形)。利用指针、虚函数printArea()分别输出以上三者的面积,3个图形的数据在定义对象时给定。 [源程序] #in clude using n amespace std; class Shape { public: virtual float area()c on st=0; virtual void display()c on st=0; }; class Circle:public Shape { public: Circle(double a):r(a){} virtual float area()co nst{return 3.14*r*r;} virtual void display()c onst { cout?"圆面积"<

class Recta ngle:public Shape { public: Rectangle(double a,double b):l(a),w(b){} virtual float area()c on st{return l*w;} virtual void display()c onst { cout?"矩形面积"<display(); m=m+p[i]->area(); {

实验三 多态性

河南**大学 实验报告 课程名称面向对象程序设计名称实验三多态性 院系_信息工程学院__ 班级__计科172 学生姓名_ ** __

实验三多态性 一.实验目的 本实验的目的是使学生了虚函数的作用,掌握多态的概念、编译时多态、运行时多态,掌握运算符重载和虚函数的用法。 二.实验环境 Visual C++ 6.0 及以上版本。 三.实验内容 熟悉掌握C++多态的相关知识。根据老师布置的实验题目,提前分析题目要求所需要的类,设计好解决题目要求需要的对象个数,设计解决问题需要的主函数等。题目可以从以下题目中选择一个。 1.定义一个实数类Real,类中包括一个数据成员real,构造函数、display()函数以及重载的+、-、*、/运算符。用公有继承方式声明一个复数类Complex,该类包括两个数据成员real,image,并重载Real类的函数和+、-、*、/运算符。编写一个复数四则运算计算器。 2.Shape是一个几何图形的基类,它至少有求自身周长函数Circumference()和求自身面积函数Area()。从Shape类派生出Circle类、Ellipse类、Triangle 类和Rectangle类,分别继承基类Shape的Circumference()和Area(),并增加新的成员。编写主函数,定义各派生类对象,求多派生类对象的周长之和、面积之和。 3.其它和本实验目的相符的题目,根据学生实际情况增加相应的题目,但题目难度不应低于以上两个题目。 注意:从以上题目中选择一个作为实验题目。 选择题目2 四、实验原理 1.按照题目要求分析解决问题需要的类; 2.进行类的设计并实现; 3.分析解决问题需要定义的对象及对象间的消息传递关系; 4.设计主函数实现题目要求。 五、数据结构和程序设计

多态与虚函数 练习题

多态与虚函数练习 选择题 单选题 1.要实现动态多态性,可以通过()调用虚函数。 A. 基类指针 B. 成员名限定 C. 对象名 D. 派生类名 2.以下()成员函数表示纯虚函数。 A. virtual int vf(int); B. void vf(int)=0; C. virtual void vf()=0; D. virtual void vf(int) { };

3.关于纯虚函数和抽象类的描述中,错误的是()。 A. 纯虚函数是一种特殊的虚函数,它没有具体的实现 B. 抽象类是指具有纯虚函数的类 C. 一个基类中说明有纯虚函数,该基类派生类一定不再是抽象类 D. 抽象类只能作为基类来使用,其纯虚函数的实现由派生类给出 4.下面4个选项中,()是用来声明虚函数的。 A. virtual B. public C. using D. false 5.下列关于动态联编的描述中,错误的是()。 A. 动态联编是以虚函数为基础 B. 动态联编是运行时确定所调用的函数代码的 C. 动态联编调用函数操作是指向对象的指针或对象引用 D. 动态联编是在编译时确定操作函数的

6.关于虚函数的描述中,()是正确的。 A. 虚函数是一个静态成员函数 B. 虚函数是一个非成员函数 C. 虚函数既可以在函数说明时定义,也可以在函数实现时定义 D. 派生类的虚函数与基类中对应的虚函数具有相同的参数个数和类型 7.下面关于友元的描述中,错误的是()。 A. 友元函数可以访问该类的私有数据成员 B. 一个类的友元类中的成员函数都是这个类的友元函数 C. 友元可以提高程序的运行效率 D. 类与类之间的友元关系可以继承 8.下面描述中,正确的是()。 A. virtual可以用来声明虚函数 B. 含有纯虚函数的类是不可以用来创建对象的,因为它是虚基类

c++多态性实验报告

实验3 多态性 实验课程名:面向对象程序设计(C++) 专业班级:学号:姓名: 实验时间:实验地点:指导教师: 3.1实验目的和要求 (1) 了解多态性的概念。 (2) 掌握运算符重载的基本方法。 (3) 掌握虚函数的定义和使用方法。 (4) 掌握纯虚函数和抽象类的概念和用法。

二、实验内容 一、构建一个复数类Complex,试对下列几个运算符进行重载:++,=,!=,+,-,==,其中要求要有成员重载形式和友元重载形式,而且,++运算符要求实现先加和后加两种形式。 该类定义原型说明: class complex { public: complex(double r=0,double i=0); complex &operator +(complex &c); complex operator -(complex &c); complex operator *(complex &c); friend complex operator /(complex &c1,complex &c2); friend int operator ==(complex &c1,complex &c2); friend int operator !=(complex &c1,complex &c2); //friend complex operator++(complex &c); complex operator++(); complex operator++(int); void disp(); private: double real; double imag; }; 实验代码如下: #include using namespace std; class complex { public: complex(){real=0;imag=0;} complex(double r,double i) { real=r;

实验八 虚函数及应用

实验八虚函数及应用 一、实验目的 1.理解虚函数与运行时(动态)多态性之间的关系,掌握虚函数的定义及应用; 2.理解纯虚函数与抽象类的概念,掌握抽象类的定义及应用; 3.理解虚析构函数的概念及作用。 二、实验学时 课内实验:2课时课外练习:2课时 三本实验涉及的新知识 ㈠虚函数与动态多态性 在C++中,如果将基类与派生类的同名成员函数定义为虚函数,就可以定义一个基类指针,当基类指针指向基类对象时访问基类的成员函数,当基类指针指向派生类对象时访问派生类的成员函数,实现在运行时根据基类指针所指向的对象动态调用成员函数,实现动态多态性。换句话说,虚函数与派生类相结合,使C++能支持运行时(动态)多态性,实现在基类中定义派生类所拥有的通用“接口”,而在派生类中定义具体的实现方法,即“一个接口,多种方法”。 ㈡虚函数的定义 1.在基类中定义 在定义函数的前面加上“virtual ”。即: virtual 返回类型函数名(参数表) { …… } 2.在派生类中定义 函数的返回类型、函数名、参数的个数、参数类型及顺序必须与基类中的原型完全相同。 3.说明: ⑴在派生类中定义虚函数时,可用“virtual”也可不用“virtual”(最好都使用)。 ⑵虚函数在派生类中重新定义时,其原型必须与基类中相同。 ⑶必须用基类指针访问虚函数才能实现运行时(动态)多态性;当用普通成员函数的调用方法(即用圆点运算符)调用虚函数时,为静态调用; ⑷虚函数在自身类中必须声明为成员函数(不能为友元函数或静态成员函数),但在另一个类中可以声明为友元函数。 ⑸虚函数可以公有继承多次,其虚函数的特性不变。 ⑹构造函数不能定义为虚函数,但析构函数可以定义为虚函数。 ⑺虚函数与重载函数的关系 ①普通函数重载是通过参数类型或参数的个数不同实现的;重载一个虚函数时,其函数原型(返回类型、参数个数、类型及顺序)完全相同。 ②当重载的虚函数只有返回类型不同时,系统将给出错误信息;如果定义的虚函数只有函数名相同,而参数个数或类型不同时,则为普通函数重载。 ㈢纯虚函数与抽象类 1.纯虚函数定义 格式:

相关文档
相关文档 最新文档