c++虚函数和纯虚函数的区别

虚函数为了重载和多态的需要,在基类中是由定义的,即便定义是空,所以子类中可以重写也可以不写基类中的函数!

纯虚函数在基类中是没有定义的,必须在子类中加以实现,很像java中的接口函数!

多态是C++的重要特性,通过基类指针来访问派生类的函数。

虚函数就是为了实现这功能而定义的函数,虚函数可以在定义时实现也可以不实现,定义了虚函数的类可以实例化。

纯虚函数更多的是表示接口的含义,纯虚函数定义时不能实现,需要在派生的子类中实现且必须实现,含有纯虚函数的类不能实例化。

虚析构函数与虚函要成对出现,以便在通过基类指针释放派生对象时,调用派生类的析构函数。

class VirtualFun
{
public:
 VirtualFun();
 ~VirtualFun();
 virtual void Hello() {std::cout<<"hello"<<std::endl;};
};

class PureVirtualFun
{
public:
 PureVirtualFun();
 virtual ~PureVirtualFun();
 virtual void Hello() = 0;
};

class APureVirtualFun : public PureVirtualFun
{
public:
 APureVirtualFun();
 virtual ~APureVirtualFun();
 virtual void Hello() {std::cout<<"hello"<<std::endl;};
};

int main()
{
 VirtualFun* a = new VirtualFun();
 PureVirtualFun* b = new APureVirtualFun();
}

C++虚函数与纯虚函数的区别

什么是虚函数?

那些被virtual关键字修饰的成员函数,就是虚函数。虚函数的作用,用专业术语来解释就是实现多态性(Polymorphism),多态性是将接口与实现进行分离;用形象的语言来解释就是实现以共同的方法,但因个体差异而采用不同的策略。

虚函数声明如下:virtual ReturnType FunctionName(Parameter);

虚函数必须实现,如果不实现,编译器将报错,错误提示为:

error LNK****: unresolved external symbol "public: virtual void __thiscall

ClassName::virtualFunctionName(void)"

 

为什么要用纯虚函数?

在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。为了解决这个问题,方便使用类的多态性,引入了纯虚函数的概念,将函数定义为纯虚函数(方法:virtual ReturnType Function()= 0;),则编译器要求在派生类中必须予以重写以实现多态性。同时含有纯虚拟函数的类称为抽象类,它不能生成对象。

 

在什么情况下使用纯虚函数(pure vitrual function)?
 

1,当想在基类中抽象出一个方法,且该基类只做能被继承,而不能被实例化;
 

2,这个方法必须在派生类(derived class)中被实现;
 

   如果满足以上两点,可以考虑将该方法申明为pure virtual function.
 

我们来举个例子,我们先定义一个形状的类(Cshape),但凡是形状我们都要求其能显示自己。所以我们定义了一个类如下:
 

class CShape
 

{
 

    virtual void Show(){};
 

};
 

但没有CShape这种形状,因此我们不想让CShape这个类被实例化,我们首先想到的是将Show函数的定义(实现)部分删除如下:
 

class CShape
{
    virtual void Show();
};
当我们使用下面的语句实例化一个CShape时:
 

CShape cs;  //这是我们不允许的,但仅用上面的代码是可以通过编译(但link时失败)。
 

 
 

   怎么样避免一个CShape被实例化,且在编译时就被发现?
 

答案是:使用pure virtual funcion.
 

我们再次修改CShape类如下:
 

class CShape
{
public:
    virtual void Show()=0;
};
这时在实例化CShape时就会有以下报错信息:
error C2259: 'CShape' : cannot instantiate abstract class due to following members:
warning C4259: 'void __thiscall CShape::Show(void)' : pure virtual function was not defined
 
我们再来看看被继承的情况,我们需要一个CPoint2D的类,它继承自CShape.他必须实现基类(CShape)中的Show()方法。
   其实使用最初的本意是让每一个派生自CShape的类,都要实现Show()方法,但时常我们可能在一个派生类中忘记了实现Show(),为了避免这种情况,pure virtual funcion发挥作用了。
   我们看以下代码:
class CPoint2D:public CShape
{
public:
 CPoint2D()
 {
  printf("CPoint2D ctor is invoked\n");
 };
 void Msg()
 {
  printf("CPoint2D.Msg() is invoked\n");
 };
 
};
 
当我们实例化CPoint2D时,在编译时(at the compiling)也会出现如下的报错:
error C2259: 'CShape' : cannot instantiate abstract class due to following members:
warning C4259: 'void __thiscall CShape::Show(void)' : pure virtual function was not defined
   如上,我们预防了在派生类中忘记实现基类方法。

时间: 2024-08-30 09:28:55

c++虚函数和纯虚函数的区别的相关文章

基础:C++中的虚函数和纯虚函数用法

1. 虚函数和纯虚函数可以定义在同一个类(class)中,含有纯虚函数的类被称为抽象类(abstract class),而只含有虚函数的类(class)不能被称抽象类 2. 虚函数可以被直接使用,也可以被子类(sub class)重载以后以多态的形式调用,而纯虚函数必须在子类(sub class)中实现该函数才可以使用. 3. 虚函数和纯虚函数都可以在子类(sub class)中被重载,以多态的形式被调用. 4. 虚函数和纯虚函数通常存在于抽象基类(abstract base class -AB

c++ 虚函数与纯虚函数的区别(深入分析)_C 语言

在面向对象的C++语言中,虚函数(virtual function)是一个非常重要的概念.因为它充分体现 了面向对象思想中的继承和多态性这两大特性,在C++语言里应用极广.比如在微软的MFC类库中,你会发现很多函数都有virtual关键字,也就是说, 它们都是虚函数.难怪有人甚至称虚函数是C++语言的精髓. 那么,什么是虚函数呢,我们先来看看微软的解释: 虚函数是指一个类中你希望重载的成员函数,当你用一个基类指针或引用指向一个继承类对象的时候,你调用一个虚函数,实际调用的是继承类的版本. 这个定

c++中虚函数和纯虚函数的作用与区别_C 语言

虚函数为了重载和多态的需要,在基类中是有定义的,即便定义是空,所以子类中可以重写也可以不写基类中的此函数! 纯虚函数在基类中是没有定义的,必须在子类中加以实现,很像java中的接口函数! 虚函数 引入原因:为了方便使用多态特性,我们常常需要在基类中定义虚函数. class Cman { public: virtual void Eat(){--}; void Move(); private: }; class CChild : public CMan { public: virtual void

C++中虚函数与纯虚函数的用法_C 语言

本文较为深入的分析了C++中虚函数与纯虚函数的用法,对于学习和掌握面向对象程序设计来说是至关重要的.具体内容如下: 首先,面向对象程序设计(object-oriented programming)的核心思想是数据抽象.继承.动态绑定.通过数据抽象,可以使类的接口与实现分离,使用继承,可以更容易地定义与其他类相似但不完全相同的新类,使用动态绑定,可以在一定程度上忽略相似类的区别,而以统一的方式使用它们的对象. 虚函数的作用是实现多态性(Polymorphism),多态性是将接口与实现进行分离,采用

[面试题]虚函数和纯虚函数

①虚函数 C++中的虚函数的作用主要是实现了多态的机制.关于多态,简而言之就是用父类型的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数.这种技术可以让父类的指针有"多种形态",这是一种泛型技术.        如果调用非虚函数,则无论实际对象是什么类型,都执行基类类型所定义的函数.非虚函数总是在编译时根据调用该函数的对象,引用或指针的类型而确定.如果调用虚函数,则直到运行时才能确定调用哪个函数,运行的虚函数是引用所绑定或指针所指向的对象所属类型定义的版本. 虚函数必须是

虚函数与纯虚函数(C++与Java虚函数的区别)的深入分析_C 语言

c++虚函数1.定义:在某基类中声明为 virtual 并在一个或多个派生类中被重新定 义的成员函数 [1]2.语法:virtual 函数返回类型 函数名(参数表) { 函数体 }3.用途:实现多态性,通过指向派生类的基类指针,访问派生类中同名覆盖成员函数,也就是允许子类override父类同名方法.虚函数的作用是实现动态联编,也就是在程序的运行阶段动态地选择合适的成员函数,在定义了虚函数后,可以在基类的派生类中对虚函数重新定义,在派生类中重新定义的函数应与虚函数具有相同的形参个数和形参类型(也

C++ 在继承中虚函数、纯虚函数、普通函数,三者的区别

1.虚函数(impure virtual) C++的虚函数主要作用是"运行时多态",父类中提供虚函数的实现,为子类提供默认的函数实现. 子类可以重写父类的虚函数实现子类的特殊化. 如下就是一个父类中的虚函数: class A { public: virtual void out2(string s) { cout<<"A(out2):"<<s<<endl; } }; 2.纯虚函数(pure virtual) C++中包含纯虚函数的

类的分解,抽象类与纯虚函数的需要性

为了不模糊概念在这里我们就简单的阐述一下类的分解,前面的教程我们着重讲述了类的继承,继承的特点就是,派生类继承基类的特性,进行结构扩张,这种逐步扩张,逐步在各派生类中分解彼此不同特性的过程其实就是类的分解. 分解过程笔者在这里不想再拿代码进行过多阐述分析了,意思说到,对于逐步分解,逐步扩张的思想就靠大家自己思考了. 拿前面交通工具类的程序进行思考,由交通工具派生出来的汽车类,飞机类,是具备更具体特性的描述的类,而对于交通工具这一个基类来说,它的特性是模糊的,广泛的,如果建立一个交通工具类的对象并

c++学习笔记之纯虚函数

首先:强调一个概念定义一个函数为虚函数,不代表函数为不被实现的函数. 定义他为虚函数是为了允许用基类的指针来调用子类的这个函数. 定义一个函数为纯虚函数,才代表函数没有被实现. 定义纯虚函数是为了实现一个接口,起到一个规范的作用,规范继承这个类的程序员必须实现这个函数.1.简介假设我们有下面的类层次: [cpp] view plaincopy class A   {   public:       virtual void foo()       {           cout<<"