当前位置: 首页 > news >正文

鹤壁高端网站建设信息推广平台

鹤壁高端网站建设,信息推广平台,黄骅市旅游景点有哪些,简历电子版模板免费下载文章目录 1、term7:Declare destructors virtual in polymorphic base classes2、总结3、相关面试题3.1 析构函数在什么情况下声明为虚函数 4、参考 1、term7:Declare destructors virtual in polymorphic base classes 带有多态性质的基类应该声明一个virtual析构函数&#x…

文章目录

  • 1、term7:Declare destructors virtual in polymorphic base classes
  • 2、总结
  • 3、相关面试题
    • 3.1 析构函数在什么情况下声明为虚函数
  • 4、参考

1、term7:Declare destructors virtual in polymorphic base classes

带有多态性质的基类应该声明一个virtual析构函数;如果class内带有任何virtual函数,它就该拥有一个virtual析构函数;
举个反面栗子:

#include <iostream>  
#include <memory>  // 基类 TimeKeeper  
class TimeKeeper {  
public:  TimeKeeper() {  std::cout << "TimeKeeper constructor called." << std::endl;  }  ~TimeKeeper() {  std::cout << "TimeKeeper destructor called." << std::endl;  }  // 假设 TimeKeeper 类有其他成员或方法...  // ...  
};  // 派生类 AtomicClock  
class AtomicClock : public TimeKeeper {  
public:  AtomicClock() {  std::cout << "AtomicClock constructor called." << std::endl;  }  ~AtomicClock() {  std::cout << "AtomicClock destructor called." << std::endl;  }  // 原子钟特有的成员或方法...  // ...  
};  // 派生类 WaterClock  
class WaterClock : public TimeKeeper {  
public:  WaterClock() {  std::cout << "WaterClock constructor called." << std::endl;  }  ~WaterClock() {  std::cout << "WaterClock destructor called." << std::endl;  }  // 水钟特有的成员或方法...  // ...  
};  // 派生类 WristWatch  
class WristWatch : public TimeKeeper {  
public:  WristWatch() {  std::cout << "WristWatch constructor called." << std::endl;  }  ~WristWatch() {  std::cout << "WristWatch destructor called." << std::endl;  }  // 腕表特有的成员或方法...  // ...  
};  // 工厂函数,返回 TimeKeeper 派生类的指针  
TimeKeeper* getTimeKeeper() {  // 这里我们简单地返回 AtomicClock 的实例,  // 但在实际中,可以根据需要返回不同派生类的实例。  return new AtomicClock();  
}  int main() {  // 从 TimeKeeper 继承体系获取一个动态分配的对象  TimeKeeper* ptk = getTimeKeeper();  // 使用 ptk 指向的对象...  // ...  // 释放内存,避免资源泄漏  delete ptk;  return 0;  
}

输出内容如下:

TimeKeeper constructor called.
AtomicClock constructor called.
TimeKeeper destructor called.

先来说一下这为什么是一个反面教材,第二个getTimeKeeper()返回的指针指向一个derived对象,而那个对象却被一个base class指针删除。因为析构的顺序,是先析构derived对象,然后再析构base对象。通过基类指针删除子类对象时,仅调用了基类的析构函数,而导致子类的Derived成分没有销毁,产生了一个“局部销毁”对象,这将导致资源泄漏、破坏数据结构、在调试器上浪费时间的严重后果。消除这个问题的做法很简单:给base class内声明一个virtual对象,这样删除对象,就会“如你所愿”。
举个栗子:

#include <iostream>  
#include <memory>  // 基类 TimeKeeper  
class TimeKeeper {  
public:  TimeKeeper() {  std::cout << "TimeKeeper constructor called." << std::endl;  }  virtual ~TimeKeeper() {  std::cout << "TimeKeeper destructor called." << std::endl;  }  // 假设 TimeKeeper 类有其他成员或方法...  // ...  
};  // 派生类 AtomicClock  
class AtomicClock : public TimeKeeper {  
public:  AtomicClock() {  std::cout << "AtomicClock constructor called." << std::endl;  }  ~AtomicClock() {  std::cout << "AtomicClock destructor called." << std::endl;  }  // 原子钟特有的成员或方法...  // ...  
};  // 派生类 WaterClock  
class WaterClock : public TimeKeeper {  
public:  WaterClock() {  std::cout << "WaterClock constructor called." << std::endl;  }  ~WaterClock() {  std::cout << "WaterClock destructor called." << std::endl;  }  // 水钟特有的成员或方法...  // ...  
};  // 派生类 WristWatch  
class WristWatch : public TimeKeeper {  
public:  WristWatch() {  std::cout << "WristWatch constructor called." << std::endl;  }  ~WristWatch() {  std::cout << "WristWatch destructor called." << std::endl;  }  // 腕表特有的成员或方法...  // ...  
};  // 工厂函数,返回 TimeKeeper 派生类的指针  
TimeKeeper* getTimeKeeper() {  // 这里我们简单地返回 AtomicClock 的实例,  // 但在实际中,可以根据需要返回不同派生类的实例。  return new AtomicClock();  
}  int main() {  // 从 TimeKeeper 继承体系获取一个动态分配的对象  TimeKeeper* ptk = getTimeKeeper();  // 使用 ptk 指向的对象...  // ...  // 释放内存,避免资源泄漏  delete ptk;  return 0;  
}

输出内容如下:

TimeKeeper constructor called.
AtomicClock constructor called.
AtomicClock destructor called.
TimeKeeper destructor called.

virtual函数的目的就是允许derived class的实现得以客制化;任何class只要带有virtual函数几乎确定应该也有一个virtual析构函数。

2、总结

书山有路勤为径,学海无涯苦作舟。

3、相关面试题

3.1 析构函数在什么情况下声明为虚函数

在面向对象的编程中,析构函数应该被声明为虚函数(virtual)当且仅当类被用作基类,并且你打算通过基类指针来删除派生类对象时(只有这么一个情况下)。这是为了防止发生所谓的“切片”问题(slicing problem)和确保正确的对象析构顺序。
当有一个基类指针指向一个派生类对象,并通过这个基类指针来调用 delete 操作符时,如果基类的析构函数不是虚函数,那么只会调用基类的析构函数,而不会调用派生类的析构函数。这会导致派生类部分的对象没有被正确地销毁,可能造成资源泄漏和其他问题。
通过将基类的析构函数声明为虚函数,可以确保当通过基类指针删除对象时,先调用派生类的析构函数,然后调用基类的析构函数,从而正确地释放所有资源。

4、参考

4.1 《More Effective C++》

http://www.mfbz.cn/news/261/

相关文章:

  • 想通过做威客网站上的任务来赚站内推广有哪些方式
  • 如何做网站授权网址百度竞价推广是什么
  • cpa做电影网站侵权吗网络营销课程个人感悟
  • 个人网站的设计与实现摘要在线crm
  • 建网站要注意的细节建站公司哪个好
  • 可以拿自己电脑做网站主机购物网站有哪些
  • 好的培训网站模板电脑系统优化软件十大排名
  • 嘉兴网红打卡景点seo建站是什么意思
  • 免费服务器推荐宝鸡百度seo
  • 手机网站开发报价如何推广网站运营
  • 中国网站的建设兰州网络推广公司哪家好
  • 政府网站内容建设管理规范济南网站优化培训
  • 怎么用php作动态网站开发中国广告网
  • 大淘客优惠券网站是怎么做的企业宣传软文范例
  • 南通网站建设项目免费个人主页网站
  • 广州大型网站建设公司图片识别 在线识图
  • 有没有免费建站永久免费开网店app
  • 珠海集团网站建设疫情最新情况 最新消息 全国
  • wordpress旅游网站主题优化大师电脑版官方免费下载
  • 怎样制作专业简历狼雨seo网站
  • 用哪个网站做相册视频文件夹网站快速优化排名排名
  • 家居企业网站建设平台免费创建自己的网站
  • wordpress中文网站模板网站内部seo优化包括
  • 可以做护考题目的网站百度网盘登录
  • 绵阳网站搜索优化播放量自助下单平台
  • wordpress 画图插件seo网站优化培
  • 网站推广外包公司哪家好打开百度网页
  • 上哪里建设个人网站买友情链接
  • 网站页面设计最宽可做多宽软文写作的技巧
  • 单位政府网站建设情况汇报湖北seo关键词排名优化软件