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

游戏门户网站模板网站百度权重查询

游戏门户网站模板,网站百度权重查询,恋爱网站建设,个人写真朋友圈文案C——继承关系中的虚函数 析构派生类纯虚构函数和抽象类 析构派生类 先看一段简单的代码&#xff1a; #include <iostream>using namespace std;class AA { public:AA() {cout << "调用了基类构造" << endl;}virtual void func() {cout <<…

C++——继承关系中的虚函数

  • 析构派生类
  • 纯虚构函数和抽象类

析构派生类

先看一段简单的代码:

#include <iostream>using namespace std;class AA
{
public:AA() {cout << "调用了基类构造" << endl;}virtual void func() {cout << "调用了基类 func()" << endl;}~AA() {cout << "调用了基类析构!" << endl;}};class BB : public AA
{
public:BB() {cout << "调用了子类构造" << endl;}void func() {cout << "调用了子类 func()" << endl;}~BB() {cout << "调用了子类析构!" << endl;}};int main() {// AA aa;BB bb;return 0;
}

编译运行的结果如下:

调用了基类构造
调用了子类构造
调用了子类析构!
调用了基类析构!

修改一下main()函数:

int main() {BB* bb_ptr = new BB;delete bb_ptr;return 0;
}

编译运行的结果与之前一样:

调用了基类构造
调用了子类构造
调用了子类析构!
调用了基类析构!

再修改一下代码,手工调用子类的析构函数:

int main() {BB* bb_ptr = new BB;bb_ptr->~BB();bb_ptr->~BB();bb_ptr->~BB();delete bb_ptr;return 0;
}

编译运行的结果如下:

调用了基类构造
调用了子类构造
调用了子类析构!
调用了基类析构!
调用了子类析构!
调用了基类析构!
调用了子类析构!
调用了基类析构!
调用了子类析构!
调用了基类析构!

可以发现,每次手工调用子类的析构函数,都会调用一次基类的析构函数。
子类的析构函数在执行完成后,会自动调用基类的析构函数。这是C++编译器强制的规定。
继续修改代码,用基类指针指向派生类new出来的对象,代码如下:

int main() {AA* aa_ptr = new BB; // 基类指针指向派生类对象delete aa_ptr; // 基类指针释放派生类对象return 0;
}

编译运行的结果如下:

调用了基类构造
调用了子类构造
调用了基类析构!

用基类指针指向派生类对象是多态的精髓。但用基类指针销毁派生对象时,不能调用派生类析构函数。在应用开发中,一般会把释放资源的代码写在析构函数中。如果析构函数未调用,会有内存泄漏的风险。
但上面这段代码运行的效果没有调用派生类的析构函数,如果需要调用派生类的虚构函数,则把基类的析构函数声明为虚构函数即可,代码如下:

#include <iostream>using namespace std;class AA
{
public:AA() {cout << "调用了基类构造" << endl;}virtual void func() {cout << "调用了基类 func()" << endl;}// 基类的析构函数是虚函数virtual ~AA() {cout << "调用了基类析构!" << endl;}};class BB : public AA
{
public:BB() {cout << "调用了子类构造" << endl;}void func() {cout << "调用了子类 func()" << endl;}~BB() {cout << "调用了子类析构!" << endl;}};int main() {AA* aa_ptr = new BB; // 基类指针指向派生类对象delete aa_ptr; // 基类指针释放派生类对象return 0;
}

编译运行的结果如下:

调用了基类构造
调用了子类构造
调用了子类析构!
调用了基类析构!

正常情况下,释放堆区内存后,会把指针指向空,防止操作野指针。delete空指针是安全的,delete野指针会导致程序的崩溃。

delete ptr;
ptr = nullptr;

如果析构函数被调用了多次,如果没有ptr = nullptr;,那么delete ptr;操作的就是野指针。
所以,在析构函数中,释放堆区内存后,也应该把指针指向空。
对于基类,即使不需要析构函数,也应该提供一个空虚析构函数。目的是为了让派生类有机会可以重写析构函数。
下面的代码就演示了,基类没有析构函数,派生类有析构函数的情况:

#include <iostream>using namespace std;class AA
{
public:AA() {cout << "调用了基类构造" << endl;}virtual void func() {cout << "调用了基类 func()" << endl;}// 基类缺少析构函数// virtual ~AA() {cout << "调用了基类析构!" << endl;} };class BB : public AA
{
public:BB() {cout << "调用了子类构造" << endl;}void func() {cout << "调用了子类 func()" << endl;}~BB() {cout << "调用了子类析构!" << endl;}};int main() {AA* aa_ptr = new BB; // 基类指针指向派生类对象delete aa_ptr; // 基类指针释放派生类对象return 0;
}

编译运行结果如下:

调用了基类构造
调用了子类构造

可以发现,销毁派生类对象时,没有调用析构函数,因为基类指针不能调用派生类的成员函数。若想调用派生类的构造函数,在基类中添加一个空的虚构函数即可。代码如下:

class AA
{
public:AA() {cout << "调用了基类构造" << endl;}virtual void func() {cout << "调用了基类 func()" << endl;}// virtual ~AA() {cout << "调用了基类析构!" << endl;}virtual ~AA() {} // 空的析构函数
};

编译运行的结果如下:

调用了基类构造
调用了子类构造
调用了子类析构!

纯虚构函数和抽象类

纯虚函数是一种特殊的虚函数,在某些情况下,基类中不能对虚函数给出有意义的实现,把它声明为纯虚函数。
纯虚函数只有函数名、参数和返回值类型,没有函数体,具体实现留给该派生类去做。
语法:virtual 返回值类型 函数名 (参数列表)=0;
纯虚函数基类中为派生类保留一个函数的名字,以便派生类它进行重定义。如果在基类中没有保留函数名字,则无法支持多态性。
含有纯虚函数的类被称为抽象类,不能实例化对象,可以创建指针和引用。
派生类必须重定义抽象类中的纯虚函数,否则也属于抽象类。
比较好理解,直接看代码:

#include <iostream>using namespace std;class AA // 含有纯虚函数的类——抽象类
{
public:AA() {cout << "调用了基类构造" << endl;}virtual void func() = 0; // 纯虚函数virtual ~AA() {cout << "调用了基类析构!" << endl;}
};class BB : public AA // 派生类
{
public:BB() {cout << "调用了子类构造" << endl;}void func() {cout << "调用了子类 func()" << endl;}~BB() {cout << "调用了子类析构!" << endl;}
};int main() {BB bb; // 创建派生类对象AA* aa_ptr = &bb; // 创建抽象类指针,指向子类对象。aa_ptr->func(); // 调用子类 func()// AA& aa_ref = bb; // 创建抽象类引用,指向子类对象。// aa_ref.func(); // 调用子类 func()return 0;
}

编译运行的效果如下:

调用了基类构造
调用了子类构造
调用了子类 func()
调用了子类析构!
调用了基类析构!

基类中的纯虚析构函数也需要实现。

class AA // 抽象类
{
public:AA() {cout << "调用了基类构造" << endl;}virtual void func() = 0;virtual ~AA() = 0;
};

这段代码编译会通过,但是链接过程中会报错。原因是:当派生类对象被销毁时,会调用派生类的析构函数,接着自动调用基类的析构函数。现在基类析构函数没有代码实现了,所以报错了。这种错误是链接阶段的,不是编译阶段的。
既然纯虚析构函数一定要有代码实现,那它还有啥意义?
有时候,想使一个类成为抽象类,但刚好又没有任何纯虚函数,怎么办?
方法很简单:在想要成为抽象类的类中声明一个纯虚析构函数。
纯虚析构函数的定义要在类的外部

class AA // 抽象类
{
public:AA() {cout << "调用了基类构造" << endl;}virtual void func() = 0;virtual ~AA() = 0; // 纯虚析构函数声明
};AA::~AA() {cout << "调用了基类析构!" << endl;}; // 纯虚析构函数定义

感谢浏览,一起学习!

http://www.hengruixuexiao.com/news/18298.html

相关文章:

  • 网站建设考察试卷谷歌搜索引擎seo
  • 网站常用颜色怎么让百度收录
  • 自己怎么做网站购买空间it行业培训机构哪个好
  • 遵义住房和城乡建设厅网站智能建站系统
  • 做网站撘框架免费网站优化排名
  • 建设网站虚拟主机网络营销做得好的企业有哪些
  • 网站动态好还是静态好搜索引擎营销方法主要有三种
  • 自适应营销网站模板站长平台百度
  • 怎样做网站xml百度推广投诉中心
  • 做外链哪个网站好东莞网站建设工作
  • 嘉兴市住房和城乡建设局网站企业网站推广外包
  • 网站站建设网络营销的优势和劣势
  • 违法网站做网站的人会受罚嘛谷歌搜索引擎镜像
  • 安徽省工程建设信息网官方网站相城seo网站优化软件
  • 长春网站建设加q479185700疫情最新消息
  • 发卡平台网站建设关键词工具
  • 网站建设7年轻人不要做网络销售
  • 网站建设高端网页设计东莞优化排名公司
  • 做网站必须学php吗广州seo网站推广平台
  • 创意性网站中山网站建设公司
  • 网站制作与美育融合seo优化方案总结
  • 如何制作电脑公司网站北京网站优化常识
  • JSP高级动态网站开发期末试卷网络营销公司热线电话
  • 上海手机网站制作公司产品设计公司
  • 兰州论坛网站建设百度托管运营哪家好
  • 最佳外贸英文网站模板最新新闻热点事件及评论
  • 来个网站吧好人一生平安2021今天新闻最新消息
  • 有谁知道教做空间的网站啊seo诊断书
  • 大型定制网站最贵建设多少钱最近一周热点新闻
  • 怎么在电脑上做网站郑州网站公司哪家好