c++中虚函数和纯虚函数定义

只有用virtual声明类的成员函数,使之成为虚函数,不能将类外的普通函数声明为虚函数。因为虚函数的作用是允许在派生类中对基类的虚函数重新定义。所以虚函数只能用于类的继承层次结构中。

一个成员函数被声明为虚函数后,在同一类族中的类就不能再定义一个非virtual的但与该虚函数具有相同的参数(包括个数和类型)和函数返回值类型的同名函数。

根据什么考虑是否把一个成员函数声明为虚函数?

①  看成员函数所在的类是否会作为基类

② 看成员函数在类的继承后有无可能被更改功能,如果希望更改其功能的,一般应该将它声明为虚函数。

如果成员函数在类被继承后功能不需修改,或派生类用不到该函数,则不要把它声明为虚函数。不要仅仅考虑到作为基类而把类中的所有成员函数都声明为虚函数。

应考虑对成员函数的调用是通过对象名还是通过基类指针或引用去访问,如果是通过基类指针或引用去访问的,则应当声明为虚函数。有时在定义虚函数时,并不定义其函数体,即纯虚函数。它的作用只是定义了一个虚函数名,具体功能留给派生类去添加。

说明:使用虚函数,系统要有一定的空间开销。当一个类带有虚函数时,编译系统会为该类构造一个虚函数表(vtbl),它是一个指针数组,存放每个虚函数的入口地址。系统在进行动态关联的时间开销很少,提高了多态性的效率。

一、虚析构函数

析构函数的作用是在对象撤销之前把类的对象从内存中撤销。通常系统只会执行基类的析构函数,不执行派生类的析构函数。

只需要把基类的析构函数声明为虚函数,即虚析构函数,这样当撤销基类对象的同时也撤销派生类的对象,这个过程是动态关联完成的。

如果将基类的析构函数声明为虚函数时,由该基类所派生的所有派生类的析构函数都自动成为虚函数,即使派生类的析构函数与基类的析构函数名字不相同。

最好把基类的析构函数声明为虚函数,这将使所有派生类的析构函数自动成为虚函数,如果程序中显式delete运算符删除一个对象,而操作对象用了指向派生类对象的基类指针,系统会调用相应类的析构函数。

构造函数不能声明为虚函数。

二、纯虚函数

有时候,基类中的虚函数是为了派生类中的使用而声明定义的,其在基类中没有任何意义。此类函数我们叫做纯虚函数,不需要写成空函数的形式,只需要声明成:

virtual 函数类型 函数名(形参表列)=0;

注意:纯虚函数没有函数体;

最后面的“=0“并不代表函数返回值为0,只是形式上的作用,告诉编译系统”这是纯虚函数”;

这是一个声明语句,最后应有分号。

纯虚函数只有函数的名字但不具备函数的功能,不能被调用。在派生类中对此函数提供定义后,才能具备函数的功能,可以被调用。

时间: 2024-10-29 02:01:03

c++中虚函数和纯虚函数定义的相关文章

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

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

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

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

C++中虚函数和纯虚函数的总结

虚函数与纯虚函数 在他们的子类中都可以被重写.它们的区别是:(1)纯虚函数只有定义,没有实现:而虚函数既有定义,也有实现的代码. 纯虚函数一般没有代码实现部分,如virtual void print() = 0; 而一般虚函数必须要有代码的实现部分,否则会出现函数未定义的错误.virtual void print(){ printf("This is virtual function\n"); }(2)包含纯虚函数的类不能定义其对象,而包含虚函数的则可以. 定义为虚函数是为了允许用基类

继承中的虚函数、纯虚函数、普通函数

一.虚函数 被virtual关键字修饰的类成员函数就是虚函数.虚函数的作用就是实现运行时的多态性,将接口与实现分离.简单理解就是相同函数有着不同的实现,但因个体差异而采用不同的策略. 基类中提供虚函数的实现,为派生类提供默认的函数实现.派生类可以重写基类的虚函数以实现派生类的特殊化.如下: class Base{ public: virtual void foo() { cout<<"Base::foo() is called"<<endl; } }; clas

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

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

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

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

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

从理论上来说,这三个概念很容易背的滚瓜烂熟,但是从大学毕业到现在,我都没真正搞明白这三个东西的出现,究竟是为了做到什么事情. 也许之前我很少写代码,更很少写面向对象的代码,即使有写多半也很容易写回到面向过程的老路上去.在写面向过程的代码的时候,根本不管什么函数重载和覆盖,想到要什么功能就变得法子的换个函数名字,心里想想:反正函数重载本质也就是入栈了两个不同的函数. 知道后来我才慢慢了解,这些概念的出现,完全就不是为了编程的功能实现,而是编程的易用和扩展,准确的来说是方便再次开发而提出的一种标准而

虚函数和纯虚函数

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

c++虚函数,纯虚函数

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

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

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