首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

C++ - 我们为什么要在类定义之外定义纯虚析构函数?

在C++中,纯虚析构函数是一个没有实现的虚析构函数,它的声明形式为virtual ~ClassName() = 0;。纯虚析构函数的存在是为了实现多态性和基类的完整性。

为什么要在类定义之外定义纯虚析构函数呢?

  1. 多态性:纯虚析构函数使得基类能够被继承并实现不同的析构行为。通过将析构函数声明为纯虚函数,可以将基类指针指向派生类对象,并在删除基类指针时调用正确的析构函数,实现多态性。
  2. 基类的完整性:在C++中,如果一个类中有纯虚函数,那么它就是一个抽象类,无法实例化对象。将纯虚析构函数定义在类定义之外,可以确保派生类在析构时能够正确调用基类的析构函数,保证了基类的完整性。

纯虚析构函数的应用场景:

  1. 抽象基类:纯虚析构函数常用于定义抽象基类,即只用于派生其他类而不用于实例化对象的类。通过将析构函数声明为纯虚函数,可以强制派生类实现自己的析构函数,确保正确的资源释放。
  2. 接口类:纯虚析构函数也常用于定义接口类,即只包含纯虚函数的类。接口类用于定义一组接口规范,派生类必须实现这些接口。通过将析构函数声明为纯虚函数,可以确保派生类在析构时能够正确调用基类的析构函数。

推荐的腾讯云相关产品和产品介绍链接地址:

腾讯云提供了丰富的云计算产品和服务,以下是与C++开发相关的一些推荐产品:

  1. 云服务器(CVM):腾讯云提供的弹性云服务器,可满足各种规模和需求的应用场景。链接地址:https://cloud.tencent.com/product/cvm
  2. 云数据库 MySQL:腾讯云提供的高性能、可扩展的云数据库服务,适用于各种规模的应用。链接地址:https://cloud.tencent.com/product/cdb_mysql
  3. 云函数(SCF):腾讯云提供的事件驱动的无服务器计算服务,可实现按需运行的函数计算能力。链接地址:https://cloud.tencent.com/product/scf

请注意,以上推荐的产品仅为示例,腾讯云还提供了更多与云计算相关的产品和服务,具体可根据实际需求进行选择。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

C++学习笔记 -- 函数函数

(void); //函数 private: int a; int b; int c; }; #endif 函数函数定义(假定名为A): #ifndef...}; #endif 其中定义函数后,A就成为了“抽象”,它是不能有实例对象的。...当且仅当里包含至少一个函数的时候,才去声明函数。 抽象是准备被用做基的,基必须要有一个函数函数会产生抽象,所以在想要成为抽象里声明一个函数。...… B::f() A::ff() //定义指向基对象的指针a,当调用f()方法时,因为f为函数,所以调用了派生的f(),输出B::f(); 参考: 详解C++中的函数函数区别)&多态性以及实例应用...C++函数、构造函数函数关系 C++函数工作原理和()继承的内存占用大小计算

1.5K40

抽象函数

函数,一般是在设计一个基时使用的,它将接口函数设置为函数后,只提供子类去继承并实现,以形成多态,除此以外不提供任何其他功能,我们称这种类为抽象(abstract)。...【函数的声明语法】 virtual 函数声明 = 0; 【函数的特征】 1、只有声明,没有实现代码。 2、含有函数称为抽象(abstract)。不能被实例化,只能被继承。...4、构造函数不能是函数,构造时,对象的创建尚未完成。构造完成后,能算一个名符其实的对象。 5、函数可以是函数且通常声明为函数。...(2, 4, 8); s->draw(); // delete 指针,调用函数 delete s; return 0; } 以上代码演示了函数定义,但上面代码存在一个问题,我们先看一下运行的结果...< “Shape destructor” << endl; } protected: int _x; int _y; }; 这样修改代码后,我们再次运行,结果就能看到,Circle 正常被了。

17330

C++要在构造函数函数中调用函数

但是为什么在构造函数中调用函数,实际上没有发生动态联编呢? 1. 不要在构造函数中调用函数的原因 第一个原因,在概念上,构造函数的工作是为对象进行初始化。...在Visual C++中,包含函数对象的指针被安排在对象的起始地址处,并且函数表(vtable)的地址是由构造函数写入指针的。...2.不要在函数中调用函数的原因 同样的,在函数中调用函数函数的入口地址也是在编译时静态决定的。也就是说,实现的是实调用而非虚调用。 考察如下例子。...的对象b退出作用域时,会先调用B的函数,然后调用A的函数,在函数~A()中,调用了函数show()。...从概念上说,函数是用来销毁一个对象的,在销毁一个对象时,先调用该对象所属函数,然后再调用其基函数,所以,在调用基函数时,派生对象的“善后”工作已经完成了,这个时候再调用在派生定义函数版本已经没有意义了

2.8K30

C++】多态 ⑤ ( 函数 | 函数语法 | 函数意义 | 父指针指向子类对象情况下父和子类使用 virtual 函数 | 代码示例 )

一、函数 1、构造函数不能是函数 构造函数 不能定义函数 , 不能使用 virtual 关键字修饰 ; 如果要创建一个 子类的 实例对象 , 需要 从 该子类的 最上层的 父开始 , 沿着继承路径...A 的构造函数 , 然后调用 B 的构造函数 , 最后调用 C 的构造函数 ; 参考 【C++】继承 ⑧ ( 继承 + 组合 模式的对象 构造函数函数 调用规则 ) 博客中 , 构造函数...成员 构造函数 ; 也就是 成员变量 类型的 构造函数 ; 最后 , 调用 自己 构造函数 ; 自身定义的 构造函数 ; 函数 : 自身 -> 成员 -> 父 ; 首先 , 调用 自己 函数...; 自身定义函数 ; 然后 , 调用 成员 函数 ; 也就是 成员变量 类型的 函数 ; 最后 , 调用 父 函数 ; 2、函数可以是函数 函数 可以是 函数 ; 函数...; 当使用 父 指针指向一个 子类 对象时 , 如果要通过 delete 释放该指针指向的对象 , 如果是正常的函数 , 没有 使用 virtual 定义函数 , 则只会调用 父函数

42520

从零开始学C++函数与多态(二):函数、抽象函数

一、函数 函数是实现多态性的前提 需要在定义共同的接口 接口要定义函数 如果基的接口没办法实现怎么办?...如形状Shape 解决方法 将这些接口定义函数 在基中不能给出有意义的函数定义,这时可以把它声明成函数,把它的定义留给派生来做 定义函数: class 名{        ...特别是在派生函数需要完成一些有意义的操作,比如释放内存 函数还可以是的。...#include  using namespace std; // 对于一个没有任何接口的,如果想要将它定义成抽象,只能将函数声明为的 // 通常情况下在基函数不需要实现...    Derived d;     return 0; } // 对于一个没有任何接口的,如果想要将它定义成抽象,只能将函数声明为的 // 通常情况下在基函数不需要实现 // 例外是函数要给出实现

1.3K00

C++编程经验(4):不要在构造函数函数中使用函数

这个事情呢,其实我们平时也不会去做的,对吧。 当然要是做了的话,那也可以做好某些天连夜加班的准备。...在基的构造过程中,函数调用从不会被传递到派生中。代之的是,派生对象表现出来的行为好象其本身就是基类型。不规范地说,在基的构造过程中,函数并没有被"构造"。...如果在基的构造过程中对函数的调用传递到了派生, 派生对象当然可以参照引用局部的数据成员,但是这些数据成员其时尚未被初始化。这将会导致无休止的未定义行为和彻夜的代码调试。...---- 函数中调用函数 在对象的期间,存在与上面同样的逻辑。一旦一个派生器运行起来,该对象的派生数据成员就被假设为是未定义的值,这样以来,C++就把它们当做是不存在一样。...一旦进入到基器中,该对象即变为一个基对象,C++中各个部分(函数,dynamic_cast运算符等等)都这样处理。

1.1K30

C++】构造函数函数概念简介 ( 构造函数函数引入 | 构造函数定义与调用 | 函数定义与调用 | 代码示例 )

" 构造函数 " 是 C++ 中的一种特殊的 " 成员函数 " , 该函数不需要用户手动调用 , 而是在 C++ 实例对象 创建时 , 自动执行的 ; " 函数 " 是 构造函数 的 对应相反的函数..., 构造函数是初始化对象 , 函数的作用是清理销毁实例对象用的 ; 二、构造函数简介 1、构造函数定义 构造函数定义 : 下面介绍 C++ 构造函数 的 声明定义 ; 构造函数名称 : 构造函数...在创建 C++ 实例对象时 , 自动调用的 构造函数 ; 手动调用 : 构造函数 也可以手动调用 , 如调用构造函数的重载函数 ; 3、代码示例 - 构造函数定义与调用 定义了一个 C++ Student...三、函数简介 ---- 1、函数定义 函数定义 : 下面介绍 C++ 函数 的 声明定义 ; 函数名称 : 函数 名称 是 ~名 ; 函数参数 : 函数 没有参数...; 函数返回值 : 函数 没有返回值 ; 2、函数调用 函数调用 : 自动调用 : C++ 编译器会 在销毁 C++ 实例对象时 , 自动调用函数 ; 3、代码示例 - 函数定义与调用

17820

C++核心准则C.127:包含函数应该有函数或保护函数

C.127: A class with a virtual function should have a virtual or protected destructor C.127:包含函数应该有函数或保护函数‍...包含函数通常(大多数情况下)通过指向基的指针使用。通常,最后一个使用者必须通过指向基的指针调用delete操作,通常是指向基的智能指针,因此函数应该是公开的函数。...稍微特殊一些的情况是:如果不希望支持通过指向基的指针销毁对象,函数应该是保护的非虚函数。参见C.35。...包含函数函数要么是公开的函数,要么是保护的非虚函数。...提示针对包含函数却没有函数的销毁操作。

74920

构造函数为什么一般不定义函数?而函数一般写成函数的原因 ?

浏览量 3 1、构造函数不能声明为函数 1)因为创建一个对象时需要确定对象的类型,而函数是在运行时确定其类型的。...而在构造一个对象时,由于对象还未创建成功,编译器无法知道对象的实际类型,是本身还是的派生等等 2)函数的调用需要函数表指针,而该指针存放在对象的内存空间中;若构造函数声明为函数,那么由于对象还未创建...,还没有内存空间,更没有函数表地址用来调用函数即构造函数了 2、函数最好声明为函数,首先函数可以为函数,当一个指向派生的基指针时,最好将基函数声明为函数,否则可以存在内存泄露的问题...如果函数不被声明成函数,则编译器实施静态绑定,在删除指向派生的基指针时,只会调用基函数而不调用派生函数,这样就会造成派生对象不完全。子类时,要调用父函数吗?...函数调用的次序时先派生后基的。和构造函数的执行顺序相反。并且函数要是virtual的,否则如果用父的指针指向子类对象的时候,函数静态绑定,不会调用子类的

59910

C++编程经验(2):为函数的必要性

这个要提一下,如果记不住就记住:如果不做函数,会有内存泄漏 解释 定义一个基的指针p,在delete p时,如果基函数函数,这时只会看p所赋值的对象,如果p赋值的对象是派生的对象,...就会调用派生函数;如果p赋值的对象是基的对象,就会调用基函数,这样就不会造成内存泄露。...如果基函数不是函数,在delete p时,调用函数时,只会看指针的数据类型,而不会去看赋值的对象,这样就会造成内存泄露。 多少学点设计模式就清楚了。...Inherit :public Base{ //此处省去,一切从简 }; //重点看调用 int main() { Base *p = new Inherit; //这种方式的调用,这时候有没有就不一样了

56210

通过C++编译视频平台为什么要使用virtual函数

大家知道TSINGSEE青犀视频云边端架构系列编译用了几种不同的架构,同时,为了满足不同形式编译的需求,我们也会在编译当中运用到不同的函数来实现。...比如在编译中,我们使用了C++语言,为了在对象不被使用之后释放资源,函数也可实现多态,我们函数加上了virtual。 C++中基函数为什么要用virtual函数?...因此,MyClass函数并没有被调用,但是正常情况下函数里都会释放各种资源,而函数不被调用的话就会导致内存泄漏。...代码1加上virtual关键字,运行次代码会调用函数,避免内存泄漏。 所以c++中基采用virtual函数主要是为了防止内存泄漏。如果派生中申请内存空间,而且在函数中对内存进行释放。...如果没有采用虚构函数,而释放该类对象,派生对象就不会得到动态绑定。这种情况就会导致内存泄漏。所以为了防止内存泄漏,只要继承关系,被继承的函数函数,都会加上virtual关键字。

52920

C++】多态 ⑧ ( 验证指向 函数表 的 vptr 指针 | 对比定义函数和没有定义函数的大小 )

对比 定义函数 与 没有定义函数 的大小 , 其它成员都相同 , 定义函数多出了 4 字节 , 多出的 4 字节就是 vptr 指针占用的内存空间 ; 一、验证指向 函数表...存储到 " 函数表 " 中 ; 函数表 创建 : 在 中使用 virtual 关键字 声明 函数 时 , C++ 编译器 会自动为该类生成 " 函数表 " ; 生成函数表的前提是 至少有...中 , 重写了 父的 virtual 函数 , 那么 C++ 编译器会在 子类 函数表 中放入该 子类函数函数指针 ; 如果 C++ 中存在 virtual 函数 , 在创建对象时 ,...; 2、函数与普通函数对比 - 多出了 vptr 指针的大小 下面的代码中 , 定义了 2 个 , 区别是 一个定义了 virtual 函数 , 另外一个没有定义 函数 ; 在 Parent...判断两个的区别 ; 最终得到 , 有 函数 , 比 没有 函数 , 多 4 字节 , 也就是一个指针的大小 , 定义函数 , 多出的 4 字节就是 vptr 指针的大小

18540

C++函数与抽象

1.函数 1.1函数简介 函数可以毫不夸张的说是C++最重要的特性之一,我们先来看一看函数的概念。...在基定义中,定义函数的一般形式为: virtual 函数返回值类型 函数名(形参表) { 函数体 } 为什么函数C++最重要的特性之一呢,因为函数承载着C++中动态联编的作用,也即多态...1.2函数的继承中,基函数一般都是函数。当基中有函数的时候,函数也要定义函数。...如果不定义函数,当删除一个指向派生对象的指针时,会调用基函数,派生函数未被调用,造成内存泄露。...2.函数与抽象 既然有了函数,那为什么还需要有函数呢?在Java编程语言中有接口的定义,在C++中虽然没有接口关键字,但是函数就完成了接口的功能。

1.5K20

轻松搞定面试中的“

函数的作用是允许在派生中重新定义与基类同名的函数,并且可以通过基指针或引用来访问基和派生中的同名函数,达到多态的目的。 2.什么是函数,什么是,有什么作用?...函数只有函数的名字而不具备函数的功能,不能被调用。它只是通知编译系统:“在这里声明一个函数,留待派生定义”。在派生中对此函数提供定义后,它才能具备函数的功能,可被调用。...因为函数是不能被调用的,包含函数是无法建立对象的。 抽象的作用是作为一个族的共同基,或者说,为一个族提供一个公共接口。 3.为什么有的函数需要设为virtual?...所以,只有当一个被用来作为基的时候,才把函数写成函数。 可以。 4.函数是否可以是函数? 可以,当需要定义一个抽象,如果其中没有其他合适的函数,可以把函数定义的。...在的时候会首先调用子类的函数掉对象中的子类部分,然后在调用基函数部分,如果在基函数里面调用函数,会导致其调用已经了的子类对象里面的函数,这是非常危险的。

65820

virtual

函数的使用就是为了方便多态的使用,常常需要在定义函数,然后对基进行继承,再对基中的函数进行重载。...此时,基函数被隐藏(注意别与覆盖混淆)。 函数 C++语言为我们提供了一种语法结构,通过它可以指明,一个虚拟函数只是提供了一个可被子类型改写的接口。...父指针=new 子类名(……); 父指针->函数名(……); 调用子类的函数 函数的实现原理 函数的实现原理: 当我们在父中通过virtual修饰函数之后,通过父指针指向子类对象...原理: 如果父当中定义函数,那么父函数表当中就会有一个父函数指针,指向的是父函数,子类函数表当中也会产生一个子类的函数的入口指针,指向的是子类的函数...抽象子类只有把抽象中所有函数都做了实现才可以实例化对象。 仅含有函数称为接口 如果在抽象中仅含有函数而不含其他东西,我们称之为接口

63950

CC++面试常问题集(2)

三,赋值运算符重载函数  赋值运算符重载函数也不会被子类继承,只是在子类的赋值运算符重载函数中会调用父的赋值运算符重载函数。 7、基函数为什么要用virtual函数?...C++中基采用virtual函数是为了防止内存泄漏 具体地说,如果派生中申请了内存空间,并在其函数中对这些内存空间进行释放。...那么在这种情况下,派生中申请的空间就得不到释放从而产生内存泄漏。所以,为了防止这种情况的发生,C++中基函数应采用virtual函数。...8、哪些函数不能声明成函数? 在C++,有五种函数不能被声明成函数,分别是:非成员函数、构造函数、静态成员函数、内联成员函数、友元函数这五种,下面分别解释为什么这五种函数不能被声明成函数。...函数必须根据对象类型才能知道调用哪一个函数,故函数是一定要在对象的基础上才可以的,两者一个是与实例相关,一个是与相关。 4.

1.1K10

c++和继承面试点25连问

,此时我们A的函数修改为virtual,看看结果: A() B() ~B() ~A() 一般情况下,只有当一个被用作基时才需要使用函数,这样做的作用是当一个基的指针删除派生的对象时...因为销毁的时候直接销毁的基指针,此时编译器只知道调用基,并不会主动去调用派生函数,所以基函数需为函数,这样运行时程序才会去调用派生函数,其实这就相当于函数的多态,...函数是否可以抛异常 可以,但是最好不要抛出,如果一定要抛出,那要在函数内部处理,保证函数能执行完成。 16....,所谓函数其实就是函数后面加= 0,此时print函数是不需要实现的,它只是定义了一个抽象接口而已。...同样的,这段代码里面的CPeople就是抽象了,某个不论是自己定义函数,还是从其他基继承了函数但却并没有实现的,都可以称为抽象,所谓抽象,其实就是具体的反义词,比方说这里只给了一个接口

90910

再探函数

那我现在有一个抽象的对象,我要调用接口,调用哪个? ---- Q5:基函数为什么定义函数?...只有在基函数定义函数时,调用操作符delete销毁指向对象的基指针时,才能准确调用派生函数(从该级向上按序调用函数),才能准确销毁数据。...: A B ~A 有的时候: A B ~B ~A ---- Q6:函数可以使函数吗?...---- Q7:构造函数函数可以调用函数吗,为什么?...因为父对象会在子类之前进行构造,此时子类部分的数据成员还未初始化,因此调用子类的函数时不安全的,故而C++不会进行动态联编; 函数是用来销毁一个对象的,在销毁一个对象时,先调用子类的函数,然后再调用基函数

85420

C++核心准则C.30:如果一个需要明确的销毁动作,定义函数

函数在对象的生命周期结束时被隐式调用。如果默认的函数已经足够,没有必要另外定义。只有在一个需要其成员函数处理之外的动作时定义非默认的函数。...Note(注意) There are two general categories of classes that need a user-defined destructor: 通常有两种情况需要用户定义函数...管理的资源没有表现为包含函数。例如vector或者事务。...如果需要默认函数,但是其产生已经被抑制(例如由于定义了移动构造函数),使用=default(明确要求生成,译者注)。...寻找有函数,即使它们所有的数据成员都有函数

34410
领券