问个关于虚析构函数问题,不是很懂

a2471388918 2013-07-16 09:12:03
#include <iostream>
using namespace std;

class Base {
public:
virtual~Base();
};
Base::~Base(){
cout<<"Base destructor "<<endl;
}

class Derived :public Base {
public:
Derived ();
~Derived();
private:
int *p;
};
Derived::Derived(){
p=new int(0);
}
Derived::~Derived(){
cout<<"Derived destructor "<<endl;
delete p;
}
void fun(Base*b){
delete b;
}
int main(){
Base *b=new Derived ();
fun(b);
return 0;
}






结果不是很明白,首先这里调用了Devired的析构函数,证明那个new Derived ();调用了Derived的构造函数,new不是开辟了用来存储后面数类型的空间,然后返回地址给左边那个吗,为什么还要初始化的(现在看国产书,没说);
还有,既然那个 virtual~Base();是虚的,那应该只调用~Derived()啊,为什么后来还调用了~Base();
大神出来吧!我是新手!
...全文
240 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaohuh421 2013-07-18
  • 打赏
  • 举报
回复
虚函数的作用楼主是知道的吧. 虚析构函数的作用跟虚函数一样, 只是有点区别, 虚析构函数会自动调用基类的函数, 普通虚函数不会.
lm_whales 2013-07-18
  • 打赏
  • 举报
回复
虚析构函数,是用在多态上的,用了来保证,delete 基类指针指向的派生类对象时,能够正确析构子类对象的。delete 会调用 析构函数 比如 class Base{ virtual ~Base(){};//<==> virtual void dtor(){}; }; class Derived{ virtual ~Derived(){}; //<==>virtual void dtor(){}; } Base *pBase =new Derived; delete pBase;//<==>{ pBase->detor(); operator delete(pBase);} <==> {pBase->~Derived();operator delete(pBase);} PS: 派生类对象析构时,会自动调用,基类对象的,析构函数--在子类析构函数,内部的代码,执行完成以后。 可以把析构函数看成是,特殊的重载函数,虽然函数名称不同。 这样在虚函数表中,派生类的析构函数,和父类的析构函数的位置,是相同的; 派生类对象的,虚函数表里的,析构函数位置,存放的是派生类的,析构函数。 所以 delete时, 通过定义,虚析构函数,如果基类指针,指向派生类对象的话,会调用派生类的析构函数。 派生类的析构函数结束时,会调用基类的析构函数; 派生类对象,和相应的基类对象,都得以析构。 如果不是虚析构函数,delete时,会直接析构基类对象,导致派生类对象的,派生类定义部分,没有析构。 产生不能完全析构的错误。
漫步者、 2013-07-16
  • 打赏
  • 举报
回复
引用 2 楼 a2471388918 的回复:
引用 1 楼 ganpengjin1 的回复:
析构顺序和你的构造顺序相反
不给分你
又不是来找你要分的,觉得说的不对,可以无视的
a2471388918 2013-07-16
  • 打赏
  • 举报
回复
引用 3 楼 haomingzidoumeilea 的回复:
参考:http://blog.csdn.net/songthin/article/details/1703966 new分三步:动态开辟空间,调用构造函数,返回对应指针 因为~Drived()只析构子类的部分,还要~Base()来析构继承父类的部分.和构造函数正好顺序相反。
我在德问找到答案了,原来是说继承的时候会构造基类的,所以还会调用析构,对吧
a2471388918 2013-07-16
  • 打赏
  • 举报
回复
引用 6 楼 ananluowei 的回复:
没有virtual,是按照指针的类型来析构,在这个多态的例子中,是析构~Base()而不析构~Derived() 有virtual,是按照指针指向的对象类型来析构,这个例子中是析构~Derived() 对于派生类来说,析构是从自己往基类一层层析构的,所以还会析构~Base() 你可以去掉基类析构的virtual再运行,结果只会有 Base destructor
我在德问找到答案了,原来是说继承的时候会构造基类的,所以还会调用析构,对吧
max_min_ 2013-07-16
  • 打赏
  • 举报
回复
构造 是 先父后子, 析构是先子后父
大尾巴猫 2013-07-16
  • 打赏
  • 举报
回复
没有virtual,是按照指针的类型来析构,在这个多态的例子中,是析构~Base()而不析构~Derived() 有virtual,是按照指针指向的对象类型来析构,这个例子中是析构~Derived() 对于派生类来说,析构是从自己往基类一层层析构的,所以还会析构~Base() 你可以去掉基类析构的virtual再运行,结果只会有 Base destructor
alexandnpu 2013-07-16
  • 打赏
  • 举报
回复
不太明白你的第一个问题, 简单来说,new 操作符有两个动作,1,分配内存;2在那个内存上调用构造函数。 对于第二个问题: 析构函数是个特殊的函数,在多态delete时候,这个是要保证父类的析构函数也要调用的。 (不知道这个是不是在标准里就定义好了的。)
Jhon_Easter 2013-07-16
  • 打赏
  • 举报
回复
基类应具有析构函数,以保证在删除指向动态分配对象的指针时,根据指针实际指向的对象所属的类型运行适当的析构函数。 上述代码中,将基类的析构函数定义为虚函数,这使得在delete指向派生类对象的指针时首先调用派生类的析构函数,再调用基类的析构函数,从而实现完整释放。 若不定义为虚函数,则存在内存未完全delete的问题。
haomingzidoumeilea 2013-07-16
  • 打赏
  • 举报
回复
参考:http://blog.csdn.net/songthin/article/details/1703966 new分三步:动态开辟空间,调用构造函数,返回对应指针 因为~Drived()只析构子类的部分,还要~Base()来析构继承父类的部分.和构造函数正好顺序相反。
a2471388918 2013-07-16
  • 打赏
  • 举报
回复
引用 1 楼 ganpengjin1 的回复:
析构顺序和你的构造顺序相反
不给分你
漫步者、 2013-07-16
  • 打赏
  • 举报
回复
析构顺序和你的构造顺序相反
代码转载自:https://pan.quark.cn/s/50df8825dc0d Tensilica Xtensa指令集架构手册是一份详尽阐述Xtensa指令集架构(ISA)的参考指南,它主要面向Tensilica公司所推出的处理器核心,尤其是LX106核,同时亦涵盖了ESP8266和ESP32等相关内容。该手册全面介绍了Xtensa处理器核心的指令集、配置选项、扩展能力以及将架构映射至硬件的详细情况。接下来将依据手册中所述的知识点进行深入解读。 ### Xtensa指令集架构(ISA) Xtensa指令集架构是Tensilica公司为其处理器产品设计的一套指令集,该指令集具备高度的可配置性和可扩展性。这一特性使得Xtensa ISA能够在不同的应用领域和硬件需求中进行个性化定制,以满足特定的功能与性能要求。 #### 可配置性(Configurability) Xtensa ISA的可配置性体现在用户可以根据实际需求对处理器的多个方面进行定制。这包括但不限于: - **指令集扩展**:用户可以根据特定的应用需求添加新的指令,从而提升处理特定任务的效率。 - **寄存器文件扩展**:根据应用需求,可以增加或优化处理器的寄存器数量和类型。 - **协处理器扩展**:通过集成特定的协处理器,可以将专门的计算任务卸载到协处理器上,从而提升整体性能。 #### 可扩展性(Extensibility) Xtensa ISA不仅可配置,还拥有卓越的可扩展性,它支持多种扩展,包括: - **状态扩展(State Extensions)**:允许处理器添加新的状态寄存器,以支持新的功能或增强现有功能。 - **指令扩展(Instruction Extensions)**:...
下载代码方式:https://pan.quark.cn/s/8779ceeac982 YOLOv5被认为是一种功能卓越且精确度高的目标检测系统,它在即时处理场景中展现出优越的性能。"基于YOLOv5的火灾检测"计划致力于运用这项尖端的计算机视觉方法,以达成对火焰和烟雾的有效辨识,进而起到防止及降低火灾事故的作用。在这个压缩文件里,用户能够获取到预先训练完成的模型,这表示使用者能够直接执行推理检测,无需从头开始训练模型。 我们现在将详细探讨YOLO(You Only Look Once)系统。YOLO是一种单阶段的目标检测方法,它将目标检测任务转化成回归问题,通过直接预测边界框和类别可能性来迅速识别图像中的物体。YOLOv5是这一系列的最新迭代,由Ultralytics团队研发,它在前几代的基础上进行了改进,包括更迅速的训练速率、更精准的检测以及更强的适应性。 YOLOv5的关键优化包含: 1. **数据增强**:应用了Mosaic数据增强技术,这是一种融合了随机缩放、翻转、裁剪及色彩调节的技巧,增强了模型的普遍适用性。 2. **更高效的架构**:运用了SPP-Block(Spatial Pyramid Pooling)和Path Aggregation Network (PANet)设计,提升了特征提取的效能和精确度。 3. **权重初始化**:采用了更优化的权重初始化策略,使模型在初始训练阶段就能更快地达到收敛。 4. **联合训练**:YOLOv5支持多尺度训练,即同步训练不同尺度的网络,以改善对小目标的检测效果。 5. **优化的损失函数**:使用了GIOU(Generalized IoU)损失函数,改进了边界框的定位。 针对火灾检测的应用,YOLOv...

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧