虚函数以及纯虚函数

  多态性是将接口与实现进行分离;用形象的语言来解释就是实现以共同的方法,但因个体差异,而采用不同的策略。

  虚函数和纯虚函数都是实现多态的重要方法。本文就这两种方法进行分析以及比较

1、虚函数

在基类中声明为 virtual 并在一个或者多个派生类被重新定义的成员函数

语法规则:virtual 函数返回类型  函数名(参数表)  {函数体}

语法分析:虚函数的声明和定义和普通的成员函数一样,只是在返回值之前加入了关键字virtual。

       在基类当中定义了虚函数,可以再子类中定义和基类中相同函数名、相同参数、相同返回值和不同实现体的虚函数

       定义为虚函数是为了让基类函数的指针或者引用来指向子类。

#include<iostream>
using namespace std;

class A
{
public:
    void fun()
    {
        cout << "A::fun()..." << endl;
    }
};

class B :public A
{
public:
    void fun()
    {
        cout << "B::fun()...." << endl;
    }
};

int main()
{
    A *a = new A;              //A类指针指向A类对象
    a->fun();
    A *b = new B;              //A类指针指向B类 对象
    b->fun();

    delete a;
    delete b;
    return 0;
}

分析代码:在上述代码中B为A的派生类,A *b=new B   是将基类的指针指向B 类对象。输出为:

显然程序没有实现我们想要的输出

#include<iostream>
using namespace std;

class A
{
public:
    virtual void fun()
    {
        cout << "A::fun()..." << endl;
    }
};

class B :public A
{
public:
    void fun()
    {
        cout << "B::fun()...." << endl;
    }
};

int main()
{
    A *a = new A;              //A类指针指向A类对象
    a->fun();
    A *b = new B;              //A类指针指向B类 对象
    b->fun();

    delete a;
    delete b;
    return 0;
}

分析:可以看出利用虚函数可以实现多态,也就是说实现了通过不同对象的接口实现了不同的功能。

在使用虚函数是需要注意:

1、不能被声明为虚函数是函数类型有:构造函数,内联函数,静态成员函数

2、与构造函数不同,析构函数要尽量使用虚函数,当派生类的对象从内存中撤销的时候,会先调用派生类的析构函数然后再调用基类的析构函数,delete撤销对象时只调用了基类的析构函数,而没有执行派生类的析构函数。对此,我们将基类的析构函数声明为虚函数。

3、在基类方法声明中使用关键字virtual,可以是相同函数名(返回值、函数名、参数表)在所有的派生类中是虚函数。

2、纯虚函数

在一些情况中,基类不能对虚函数给出有意义的实现,而把它声明为纯虚函数,它的实现由它的派生类去做。

语法规则:virtual  返回值   函数名(参数表)=0;

语法分析:纯虚函数可以让类先具有一个实现功能的名字,没有给出具体实现该功能的方法。凡是含有纯虚函数的类都叫抽象类

      这种类不能声明对象,只能作为基类去被继承,由子类去重写函数体,实现函数功能。

#include<iostream>
using namespace std;

class Shope
{
public:
    virtual double GetArea() = 0;           //定义为纯虚函数
    virtual double GetCir() = 0;            //定义为纯虚函数
};

class Circle :public Shope
{
public:
    Circle(float r):r(r){}
    double GetArea()                        //函数重写
    {
        return r * r*3.14;
    }
    double GetCir()                            //函数重写
    {
        return 3.14 * 2 * r;
    }
private:
    float r;
};

class Rectangle :public Shope
{
public:
    Rectangle(float a,float b):a(a),b(b){}
    double GetArea()                        //函数重写
    {
        return a * b;
    }
    double GetCir()                            //函数重写
    {
        return (a + b) * 2;
    }
private:
    float a;
    float b;
};

int main()
{
    Shope *ci = new Circle(4);           //基类指针指向Circle对象
    cout << "半径为4的圆周长为" << ci->GetCir() << ",面积为" << ci->GetArea() << endl;

    Shope *rec = new Rectangle(4.2, 5.3);//基类指针指向Rectangle对象
    cout << "长为4.2,宽为5.3的矩形,周长为" << rec->GetCir() << ",面积为" << rec->GetArea() << endl;
    return 0;
}

分析:在shope类中,声明的两个纯虚函数,GetArea(),GetCir();Circle类和Rectangle类去继承基类,重写纯虚函数。

   根据不同的形状,由不同的计算周长和面积的方法,具体实现方法需要派生类自己去重载。

使用纯虚函数的注意:

1、纯虚函数一定没有定义,它是用来规范派生类的行为,即接口。包含纯虚函数的抽象类,不能定义实例,但是可以声明指向该抽象类的具体类的指针或者引用

2、基类的纯虚函数在派生类中必须全部定义,否则派生类依然是抽象类,无法实例化。

3、总结

1、纯虚函数是特殊的虚函数,在纯虚函数中,同样可以让基类的指针指向子类对象。

2、纯虚函数:只提供一个接口,具体实现方法需要派生类自己去重载

   虚函数:提供接口,并提供默认的实现方法;派生类也可以根据需要自己去重载

  两者区别:纯虚函数在基类中不会提供实现方法,而虚函数需要提供。

原文地址:https://www.cnblogs.com/aaakihi/p/11743050.html

时间: 2024-10-19 23:54:46

虚函数以及纯虚函数的相关文章

虚函数和纯虚函数的作用与区别

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

C++ 虚函数与纯虚函数 浅析

[摘要] 本文首先简述虚函数与纯虚函数的定义,然后分析比较两者的区别与联系(DWS). [正文] 1)虚函数与纯虚函数有什么区别? 虚函数,不代表函数为不被实现的函数,为了允许用基类的指针来调用子类的这个函数:允许被其子类重新定义的成员函数. 纯虚函数,才代表函数没有被实现,为了实现一个接口,起到一个规范的作用,规范继承这个类的程序员必须实现这个函数. 2)虚就虚在所谓"推迟联编"或者"动态联编"上,一个类函数的调用并不是在编译时刻被确定的,而是在运行时刻被确定的.

C++中虚函数和纯虚函数的作用与区别-详解

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

虚函数和纯虚函数

虚函数为了重写和多态的需要,在基类中是有定义的,即便定义是空,所以子类中可以重写也可以不写基类中的此函数! 纯虚函数在基类中是没有定义的,必须在子类中加以实现,很像java中的接口函数! 1.动态绑定 在执行期间(非编译期)判断所引用对象的实际类型,根据实际类型(动态类型)调用相应的方法. 动态绑定灵活性相对静态绑定来说要高,因为它在运行之前可以进行选择性的绑定,但同时,动态绑定的执行效率要低些,因为绑定对象还要进行编译(现在编译期一般都会多次编译). 触发动态绑定的条件:(1)只有指定为虚函数

c++虚函数,纯虚函数

1.虚函数和纯虚函数可以定义在同一个类中,含有纯虚函数的类被称为抽象类,而只含有虚函数的类不能被称为抽象类. 2.虚函数可以被直接使用,也可以被子类重载以后,以多态的形式调用,而纯虚函数必须在子类中实现该函数才可以使用,因为纯虚函数在基类有声明而没有定义. 3.虚函数和纯虚函数都可以在子类中被重载,以多态的形式被调用. 4.虚函数和纯虚函数通常存在于抽象基类之中,被继承的子类重载,目的是提供一个统一的接口. 5.虚函数的定义形式:virtual{};纯虚函数的定义形式:virtual  { }

【C++】C++中的虚函数与纯虚函数

C++中的虚函数 先来看一下实际的场景,就很容易明白为什么要引入虚函数的概念.假设我们有一个基类Base,Base中有一个方法eat:有一个派生类Derived从基类继承来,并且覆盖(Override)了基类的eat:继承表明ISA(“是一个”)的关系,现在我们有一个基类的指针(引用)绑定到派生类对象(因为派生类对象是基类的一个特例,我们当然可以用基类指针指向派生类对象),当我们调用pBase->eat()的时候,我们希望调用的是Derived类的eat,而实际上调用的是Base类的eat,测试

C++ 虚函数 、纯虚函数、接口的实用方法和意义

也许之前我很少写代码,更很少写面向对象的代码,即使有写多半也很容易写回到面向过程的老路上去.在写面向过程的代码的时候,根本不管什么函数重载和覆盖,想到要什么功能就变得法子的换个函数名字,心里想想:反正函数重载本质也就是入栈了两个不同的函数. 回过头来讲,让我了解标题这三个概念的实际用处,还是在于我这第四次重写毕业论文的代码,将它改写成面向对象的时候,才理解的.在面向对象设计的过程中, 类是从抽象逐渐具体起来的,父类可以是非常非常抽象的东西,而最终实例化的子类就非常具体了.在这个继承的过程中,不断

转 理解虚基类、虚函数与纯虚函数的概念

原文地址:理解虚基类.虚函数与纯虚函数的概念 引言 一直以来都没有写过一篇关于概念性的文章,因为我觉得这些概念性的东西书本上都有并且说的也很详细写来也无用,今天突发奇想想写 一写,下面就和大家讨论一下虚基类.虚函数与纯虚函数,一看名字就让人很容易觉得混乱.不过不要紧待看完本文后你就会理解了. 正文 虚基类        在说明其作用前先看一段代码 class A { public:     int iValue; }; class B:public A { public:     void bP

虚函数和纯虚函数的区别

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

理解虚基类、虚函数与纯虚函数的概念

总结 虚基类     1, 一个类可以在一个类族中既被用作虚基类,也被用作非虚基类.     2, 在派生类的对象中,同名的虚基类只产生一个虚基类子对象,而某个非虚基类产生各自的子对象.     3, 虚基类子对象是由最派生类的构造函数通过调用虚基类的构造函数进行初始化的.     4, 最派生类是指在继承结构中建立对象时所指定的类.     5, 派生类的构造函数的成员初始化列表中必须列出对虚基类构造函数的调用:如果未列出,则表示使用该虚基类的缺省构造函数.     6, 从虚基类直接或间接派