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

一、虚函数

被virtual关键字修饰的类成员函数就是虚函数。虚函数的作用就是实现运行时的多态性,将接口与实现分离。简单理解就是相同函数有着不同的实现,但因个体差异而采用不同的策略。

基类中提供虚函数的实现,为派生类提供默认的函数实现。派生类可以重写基类的虚函数以实现派生类的特殊化。如下:

class Base{

public:

virtual void foo() { cout<<"Base::foo() is called"<<endl; }

};

class Derived : public Base {

public:

void foo() { cout<<"Derived::foo() is called"<<endl; }

};

int main(void)

{

Base *b = new Derived();

b->foo(); // b虽然是类型Base的指针 但是实际上指向的是Derived类 所以调用的函数foo是Derived类的

return 0;

}

二、纯虚函数

纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加"=0"。

包含纯虚函数的类被称为“抽象类”,抽象类不能实例化成对象,但是可以定义抽象类的引用和指针。此外,实现了该纯虚函数的派生类可以实例化成对象。

class A

{

public:
        virtual void out1(string s)=0;
        virtual void out2(string s)
       {
           cout<<"A(out2):"<<s<<endl;
       }

};

三、普通函数

普通函数是静态编译的,没有运行时多态,只会根据指针或引用的“字面值”类对象,调用自己的普通函数。

普通函数是基类为派生类提供的“强制实现”。

因此,在继承关系中,派生类不应该重写基类的普通函数,因为函数的调用只与类对象的字面值有关。下面是搬来的一段代码:

#include <iostream>

using namespace std;

class A

{

public:
     virtual void out1()=0;  ///由子类实现
     virtual ~A(){};
     virtual void out2() ///默认实现
     {
         cout<<"A(out2)"<<endl;
     }
     void out3() ///强制实现
     {
         cout<<"A(out3)"<<endl;
     }

};

class B:public A

{

public:
     virtual ~B(){};
     void out1()
     {
         cout<<"B(out1)"<<endl;
     }
     void out2()
     {
         cout<<"B(out2)"<<endl;
     }
     void out3()
     {
         cout<<"B(out3)"<<endl;
     }

};

int main()

{
     A *ab=new B;
     ab->out1();
     ab->out2();
     ab->out3();
     cout<<"************************"<<endl;
     B *bb=new B;
     bb->out1();
     bb->out2();
     bb->out3();

delete ab;
     delete bb;
     return 0;

}

执行结果:

B<out1>

B<out2>

A<out3>

*****************************************

B<out1>

B<out2>

B<out3>

四、虚函数与构造函数和析构函数

1) 当存在类继承并且析构函数中有必须要进行的操作时(如需要释放某些资源,或执行特定的函数)析构函数需要是虚函数,否则若使用父类指针指向子类对象,在delete时只会调用父类的析构函数,而不能调用子类的析构函数,从而造成内存泄露或达不到预期结果;

2) 构造函数不能为虚函数:构造函数在进行调用时还不存在父类和子类的概念,父类只会调用父类的构造函数,子类调用子类的,因此不存在动态绑定的概念;但是构造函数中可以调用虚函数,不过并没有动态果,只会调用本类中的对应函数;

3) 静态成员函数不能为虚函数:静态成员函数是以类为单位的函数,与具体对象无关,虚函数是与对象动态绑定的。

这篇博客介绍的比较详细,我就不搬了……

参考文献:

1> C++ 虚函数表解析

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

3> C++里神奇的虚函数

4> 虚函数实现机制、构造函数、析构函数能否为虚函数,与纯虚函数

原文地址:https://www.cnblogs.com/Lilu-1226/p/10776873.html

时间: 2024-07-30 13:50:45

继承中的虚函数、纯虚函数、普通函数的相关文章

C++中的 虚函数 纯虚函数 虚基类(virtual)

前言:需要了解三者的区别,必须要掌握多态的三个必要条件: 继承 重载 父类指针指向子类对象. 虚函数 纯虚函数 虚基类三者区别 1.虚函数是用于多态中virtual修饰父类函数,确保父类指针调用子类对象时,运行子类函数的. 2.纯虚函数是用来定义接口的,也就是基类中定义一个纯虚函数,基类不用实现,让子类来实现. 3.虚基类是用来在多继承中,比如菱形继承中,如果两个父类继承自同一个类,就只实例化一个父类 ①虚函数第一个是没有使用多态(只用继承)的一般实现方式: class A { public:

虚函数/纯虚函数/抽象类/接口/虚基类

1.多态 在面向对象语言中,接口的多种不同实现方式即为多态.多态是指,用父类的指针指向子类的实例(对象),然后通过父类的指针调用实际子类的成员函数. 在Java中,没有指针,就直接用父类实例化子类对象 多态性就是允许将子类类型的指针赋值给父类类型的指针,多态是通过虚函数实现的,多态可以让父类的指针有“多种形态”,这是一种泛型技术. 所谓泛型技术,就是试图使用不变的代码来实现可变的算法 2.虚函数 在基类的类定义中,定义虚函数的一般形式: Virtual 函数返回值类型 虚函数名(形参表){ 函数

C++中的抽象类及纯虚函数的实现与否

1.含有纯虚函数的叫抽象类 2.抽象类(一般是基类)中的纯虚函数无论函数体实现与否,都没有关系,系统会自动忽略 3.继承自抽象类的子类,必须要实现父类的纯虚函数才可以实例化对象 4.抽象类不允许实例化对象,只能作为一个基类或虚接口使用 5.抽象类的指针可以指向不同的派生类对象(虚函数的功能) class Father{ public: virtual void fun() = 0{ int a = 10; };//抽象类中的纯虚函数,函数体实现了也相当于没实现,自动忽略 }; Father f;

C++ 虚函数&amp;纯虚函数&amp;抽象类&amp;接口&amp;虚基类(转)

http://www.cnblogs.com/fly1988happy/archive/2012/09/25/2701237.html 1. 多态 在面向对象语言中,接口的多种不同实现方式即为多态.多态是指,用父类的指针指向子类的实例(对象),然后通过父类的指针调用实际子类的成员函数. 多态性就是允许将子类类型的指针赋值给父类类型的指针,多态是通过虚函数实现的. 多态可以让父类的指针有“多种形态”,这是一种泛型技术.(所谓泛型技术,就是试图使用不变的代码来实现可变的算法). 2. 虚函数 2.1

【C/C++学院】0823-静态联合编译与动态联合编译/父类指针子类指针释放/虚函数/纯虚函数概念以及虚析构函数/抽象类与纯虚函数以及应用/虚函数原理/虚函数分层以及异质链表/类模板的概念以及应用

静态联合编译与动态联合编译 #include <iostream> #include <stdlib.h> //散列 void go(int num) { } void go(char *str) { } //class //::在一个类中 class A { public: void go(int num) { } void go(char *str) { } }; void main() { ///auto p = go;编译的阶段,静态联编 void(*p1)(char *s

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

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

【转载】 C++多继承中重写不同基类中相同原型的虚函数

本篇随笔为转载,原文地址:C++多继承中重写不同基类中相同原型的虚函数. 在C++多继承体系当中,在派生类中可以重写不同基类中的虚函数.下面就是一个例子: class CBaseA { public: virtual void TestA(); }; class CBaseB { public: virtual void TestB(); }; class CDerived : public CBaseA, public CBaseB { public: virtual void TestA()

C++学习笔记(十二):类继承、虚函数、纯虚函数、抽象类和嵌套类

类继承 在C++类继承中,一个派生类可以从一个基类派生,也可以从多个基类派生. 从一个基类派生的继承称为单继承:从多个基类派生的继承称为多继承. 1 //单继承的定义 2 class B:public A 3 { 4 < 派生类新定义成员> 5 }; 6 //多继承的定义 7 class C:public A,private B 8 { 9 < 派生类新定义成员> 10 }; 我们这篇主要说单继承. 派生类共有三种C++类继承方式: 公有继承(public) 基类的公有成员和保护成

C++中纯虚函数

1.纯虚函数 virtual ReturnType Function()= 0; 纯虚函数可以让类先具有一个操作名称,而没有操作内容,让派生类在继承时再去具体地给出定义.凡是含有纯虚函数的类叫做抽象类.这种类不能声明对象,只是作为基类为派生类服务.除非在派生类中完全实现基类中所有的的纯虚函数,否则,派生类也变成了抽象类,不能实例化对象. 一般而言纯虚函数的函数体是缺省的,但是也可以给出纯虚函数的函数体(此时纯虚函数变为虚函数),这一点经常被人们忽视,调用纯虚函数的方法为baseclass::vi