虚函数和抽象类
虚函数的使用
抽象类的概念和定义
纯虚函数的使用主要内容
虚函数是动态联编的基础。
是非静态的成员函数。
在类的定义中,在函数原型之前写 virtual。
virtual 只用来说明类定义中的原型,不能用在函数实现时。
具有继承性,基类中定义了虚函数,派生类中无论是否说明,同原型函数都自动为虚函数。
本质:不是重载定义而是覆盖定义。
调用方式:通过基类指针或引用,执行时会根据 指针指向的对象的类,决定调用哪个函数。
虚函数的使用写出运行结果
#include <iostream.h>
class B0 //基类声明
{
public,//外部接口
virtual void display() //虚成员函数
{cout<<"B0::display()"<<endl;}
};
class B1,public B0 //公有派生
{ public:
void display()
{ cout<<"B1::display()"<<endl; }
};
class D1,public B1 //公有派生
{ public:
void display()
{ cout<<"D1::display()"<<endl; }
};
void fun(B0 *ptr) //普通函数
{ ptr->display(); }
void main() //主函数
{ B0 b0,*p; //声明基类对象和指针
B1 b1; //声明派生类对象
D1 d1; //声明派生类对象
p=&b0;
fun(p); //调用基类 B0函数成员
p=&b1;
fun(p); //调用派生类 B1函数成员
p=&d1;
fun(p); //调用派生类 D1函数成员
}
程序的运行结果为:
B0::display()
B1::display()
D1::display()
虚函数用于实现不同对象有不同的行为,
是实现运行时多态的基础,是 针对对象而言的。
而构造函数是在对象尚未完全建立起来的时候执行的。 因此将构造函数声明为虚函数是没有意义的。
虚函数与构造函数
例 1 示例虚函数与析构函数
析构函数可以是虚函数,也往往被定义为虚函数。
一般来说,若某类中有虚函数,则其析构函数也应当定义为虚函数。
如果一个类的析构函数是虚函数,那么由它派生的所有子类的析构函数都是虚函数。保证对象的销毁工作彻底完成。
虚函数与析构函数纯虚函数与抽象类抽象类纯虚函数
Square
draw();
area();
Circle
draw();
area();
Shape
draw();//虚
area();//虚
setvalue();
int x,y;
抽象类是一种特殊的类,专门作为基类派生新类,自身无法实例化,也就是无法定义抽象类的对象,它为一类族提供统一的操作界面。
抽象类是为了抽象和设计的目的而建立的,可以说,建立抽象类,就是为了通过它多态地使用其中的成员函数。
抽象类处于类层次的上层,由它派生新类,然后再实例化。
抽象类纯虚函数 --一个类族的公共接口
纯虚函数在声明时要在函数原型的后面赋 0。
声明纯虚函数的一般格式如下:
virtual <返回值类型 > <函数名 >(<参数表 >)=0;
声明为纯虚函数之后,抽象类中就不再给出函数的实现部分。
例 5-5
抽象类不能定义自己的对象,但能说明指向抽象类的指针和引用。此外,切记抽象类不用作参数类型、函数返回值,或作 显式类型转换。
派生类只有实现了基类中所有的纯虚函数,才能定义自己的对象,不再是抽象类。
派生类改写的这些函数仍然保持虚函数的特征。
抽象类和纯虚函数示例
#include <iostream.h>
class B0 //抽象基类 B0声明
{
public,//外部接口
virtual void display( )=0;
};
写出运行结果
class B1,public B0 //公有派生
{
public:
void display(){cout<<"B1::display()"<<endl;}
};
class D1,public B1 //公有派生
{
public:
void display(){cout<<"D1::display()"<<endl;}
};
void fun(B0 *ptr) //普通函数
{ ptr->display(); }
void main() //主函数
{ B0 *p; //声明抽象基类指针
B1 b1; //声明派生类对象
D1 d1; //声明派生类对象
p=&b1;
fun(p); //调用派生类 B1函数成员
p=&d1;
fun(p); //调用派生类 D1函数成员
}
程序的运行结果为:
B1::display()
D1::display()
虚函数的使用
抽象类的概念和定义
纯虚函数的使用主要内容
虚函数是动态联编的基础。
是非静态的成员函数。
在类的定义中,在函数原型之前写 virtual。
virtual 只用来说明类定义中的原型,不能用在函数实现时。
具有继承性,基类中定义了虚函数,派生类中无论是否说明,同原型函数都自动为虚函数。
本质:不是重载定义而是覆盖定义。
调用方式:通过基类指针或引用,执行时会根据 指针指向的对象的类,决定调用哪个函数。
虚函数的使用写出运行结果
#include <iostream.h>
class B0 //基类声明
{
public,//外部接口
virtual void display() //虚成员函数
{cout<<"B0::display()"<<endl;}
};
class B1,public B0 //公有派生
{ public:
void display()
{ cout<<"B1::display()"<<endl; }
};
class D1,public B1 //公有派生
{ public:
void display()
{ cout<<"D1::display()"<<endl; }
};
void fun(B0 *ptr) //普通函数
{ ptr->display(); }
void main() //主函数
{ B0 b0,*p; //声明基类对象和指针
B1 b1; //声明派生类对象
D1 d1; //声明派生类对象
p=&b0;
fun(p); //调用基类 B0函数成员
p=&b1;
fun(p); //调用派生类 B1函数成员
p=&d1;
fun(p); //调用派生类 D1函数成员
}
程序的运行结果为:
B0::display()
B1::display()
D1::display()
虚函数用于实现不同对象有不同的行为,
是实现运行时多态的基础,是 针对对象而言的。
而构造函数是在对象尚未完全建立起来的时候执行的。 因此将构造函数声明为虚函数是没有意义的。
虚函数与构造函数
例 1 示例虚函数与析构函数
析构函数可以是虚函数,也往往被定义为虚函数。
一般来说,若某类中有虚函数,则其析构函数也应当定义为虚函数。
如果一个类的析构函数是虚函数,那么由它派生的所有子类的析构函数都是虚函数。保证对象的销毁工作彻底完成。
虚函数与析构函数纯虚函数与抽象类抽象类纯虚函数
Square
draw();
area();
Circle
draw();
area();
Shape
draw();//虚
area();//虚
setvalue();
int x,y;
抽象类是一种特殊的类,专门作为基类派生新类,自身无法实例化,也就是无法定义抽象类的对象,它为一类族提供统一的操作界面。
抽象类是为了抽象和设计的目的而建立的,可以说,建立抽象类,就是为了通过它多态地使用其中的成员函数。
抽象类处于类层次的上层,由它派生新类,然后再实例化。
抽象类纯虚函数 --一个类族的公共接口
纯虚函数在声明时要在函数原型的后面赋 0。
声明纯虚函数的一般格式如下:
virtual <返回值类型 > <函数名 >(<参数表 >)=0;
声明为纯虚函数之后,抽象类中就不再给出函数的实现部分。
例 5-5
抽象类不能定义自己的对象,但能说明指向抽象类的指针和引用。此外,切记抽象类不用作参数类型、函数返回值,或作 显式类型转换。
派生类只有实现了基类中所有的纯虚函数,才能定义自己的对象,不再是抽象类。
派生类改写的这些函数仍然保持虚函数的特征。
抽象类和纯虚函数示例
#include <iostream.h>
class B0 //抽象基类 B0声明
{
public,//外部接口
virtual void display( )=0;
};
写出运行结果
class B1,public B0 //公有派生
{
public:
void display(){cout<<"B1::display()"<<endl;}
};
class D1,public B1 //公有派生
{
public:
void display(){cout<<"D1::display()"<<endl;}
};
void fun(B0 *ptr) //普通函数
{ ptr->display(); }
void main() //主函数
{ B0 *p; //声明抽象基类指针
B1 b1; //声明派生类对象
D1 d1; //声明派生类对象
p=&b1;
fun(p); //调用派生类 B1函数成员
p=&d1;
fun(p); //调用派生类 D1函数成员
}
程序的运行结果为:
B1::display()
D1::display()