C++——虚函数、虚析构函数、纯虚函数、抽象类
创始人
2024-03-08 16:37:17

目录

一、虚函数

1、什么是虚函数?

2、虚函数的作用

 3、虚函数的参数

4、虚函数代码示例

二、虚析构函数

1、什么是虚析构函数?

2、虚析构函数的作用

 3、 构造函数

4、为什么构造函数不能是虚函数?

5、构造函数和虚析构函数的联系

6、为什么程序员不能调构造函数,但是可以调用析构函数?

7、虚析构函数产生多态

三、纯虚函数

1、定义:

2、纯虚函数的一般格式

 3、例题理解

四、抽象类

1、抽象类的定义

2、抽象类的主要作用 

一、虚函数

1、什么是虚函数?

  •   被 virtual 关键字修饰的成员函数称为虚函数。
  •  在类中定义了虚函数就会有一个虚函数表(vftable),对象模型中就含有一个指向虚表的指针(__vfptr)。在定义对象时构造函数设置虚表指针指向虚函数表。
  • 使用指针和引用调用虚函数,在编译只需要知道函数接口,运行时指向具体对象,才能关联具体对象的虚方法(通过虚函数指针查虚函数表得到具体对象中的虚方法)。

2、虚函数的作用

     实现多态性,即通过基类访问派生类的函数。

 3、虚函数的参数

  虚函数的参数值是默认静态绑定的,在子类中 重新定义虚函数的时候,并没有重新定义继承而来的参数值;除非是在实际调用过程中传递了想用的参数。 

4、虚函数代码示例

class Parent
{
public:virtual void fn(int a = 10)//如果虚函数有值,虚函数的参数值是默认静态绑定{cout << "parent fn a=" << a<fn(200);//chlid fn b=200;p->fn();//child fn b=10;产生了动态绑定,但是虚函数的参数是默认绑定cc.fn();//child fn b=100;
}

二、虚析构函数

1、什么是虚析构函数?

  •       派生类的析构函数会自动调用基类的析构函数。 只要基类的析构函数是虚函数,那么派生类的析构函数不论是否用virtual关键字声明,都自动成为虚析构函数
  •      一般来说,一个类如果定义了虚函数,则最好将析构函数也定义成虚函数。 析构函数可以是虚函数,但是构造函数不能是虚函数。(第4点有具体原因说明)
  • 注意:类中没有虚函数,就不要把析构函数定义为虚。
    在动态分配内存时所有C++的标准库函数都采用这种格式。

2、虚析构函数的作用

为了解决基类指针指向派生类对象,并用基类的指针删除派生类对象。  

 3、 构造函数

构造函数是类的一个特殊的成员函数 :

  • 1)  当一个对象的生命周期结束时,系统会自动调用析构函数注销该对象并进行善后工作,对象自身也可以调用析构函数;
  • 2)析构函数的善后工作是:释放对象在生命期内获得的资源(如动态分配的内存,内核资源);
  • 3)  析构函数也用来执行对象即将被撤销之前的任何操作。

4、为什么构造函数不能是虚函数?

       根据赋值兼容规则,可以用基类的指针指向派生类对象,如果使用基类型指针指向动态创建的派生类对象,由该基类指针撤销派生类对象,则必须将析构函数定义为虚函数,实现多态性,自动调用派生类析构函数,否则可能存在内存泄漏问题

总结:在实现运行时的多态,无论其他程序员怎样调用析构函数都必须保证不出错,所以必须把析构函数定义为虚函数。

5、构造函数和虚析构函数的联系

  • 如果构造函数可以定义为虚构造函数,使用指针调用虚构造函数,
  • 如果编译器采用静态联编,构造函数就不能为虚函数。
  • 如果采用动态联编,运行时指针指向具体对象,使用指针调用构造函数,相当于已经实例化的对象在调用构造函数,这是不容许的调用,对象的构造函数只执行一次。 

6、为什么程序员不能调构造函数,但是可以调用析构函数?

原因:

  •      虚函数调用只需要"部分的"信息,即只需要知道函数接口,而不需要对象的具体类型。但是构建一个对象,却必须知道具体的类型信息。
  •      如果你调用一个虚构造函数,编译器无法知道你想构建是继承树上的哪种类型,所以构造函数不能为虚。

7、虚析构函数产生多态

多态特例——虚析构函数产生多态;
类有指针作为数据成员,必须要写析构函数,如果当前类被继承了,则析构函数写成virtual
为了实现多态,将子类的空间被合理的释放,防止内存泄露 。

class A {
public:A(){cout << "A" << endl;m_i = new int;}virtual ~A(){cout << "~A" << endl;delete m_i;}
private:int* m_i;
};
class B :public A
{
public:B(){cout << "B" << endl;m_j = new int;}virtual ~B(){cout << "~B" << endl;delete[]m_j;}
private:int* m_j;};
void test(A* pb)
{;
}
int main()
{A* pb = new B;//new B类对象,先调用基类构造函数,再调用子类构造函数,delete pb;//pb指向子类对象,但是pb是A类类型指针,所以只析构了A,没有调子类类型的析构函数,存在内存泄漏。}

三、纯虚函数

1、定义:

       纯虚函数(pure virtual function)是指没有具体实现的虚成员函数。它用于这样的情况:设计一个类型时,会遇到无法定义类型中虚函数的具体实现,其实现依赖于不同的派生类。

2、纯虚函数的一般格式

                          virtual返回类型函数名(参数表)=0;
“=0"表明程序员将不定义该虚函数实现,没有函数体,只有函数的声明;函数的声明是为了在虚函数表中保留一个位置。在虚函数()的基础上=0;“=0“体质上是将指向函数体的指针定义为nullptr。

 3、例题理解

 题目:
设计一个形状类——有矩形、圆形、三角形;分别计算三种图形的周长和面积;

class Shape
{
public:virtual void Area() = 0;//纯虚函数就是在虚函数的基础上给个0virtual void Girth() = 0;//相当于把函数指针指向空};
class Rectangle :public Shape
{
public:virtual void Area() { cout << "Rectangle area"<< m_length*m_width << endl; }virtual void Girth(){ cout << "Rectangle girth " << 2*(m_length+m_width)<Area();p->Girth();
}int main()
{Shape* pf[3];pf[0] = new Rectangle;pf[1] = new Circle;pf[2] = new Triangle;for (int i = 0;i < 3;i++){pf[i]-> Area();pf[i]->Girth();delete pf[i];pf[i] = NULL;}/*Shape s;s.Area();s.Girth();*/
}

四、抽象类

1、抽象类的定义

  • 含有纯虚函数的类是抽象类。
  • 抽象类是一种特殊的类,它是为抽象的目而建立的,它处于继承层次结构的较上层。
  • 抽象类不能实例化对象,因为纯虚函数没有实现部分,所以含有纯虚函数类型不能实例化对象;
  • 注意:1)在定义纯虚函数时,不能定义虚函数的实现部分;

    2)在没有重新定义这种纯虚函数之前,是不能调用这种函数的。

2、抽象类的主要作用 

  • 将相关的类型组织在一个继承层次结构中,抽象类为派生类型提供一个公共的根,相关的派生类型。
  •  为了派生子类,作为当前类族最上面的基类出现,则在子类中必须要重写基类中的纯虚函数(具体类)。
  • 如果在子类中没有实现纯虚函数,则子类也是抽象类。

如有错误,敬请指正。

您的收藏与点赞都是对我最大的鼓励和支持!

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...