📜  C ++ |虚函数|问题12(1)

📅  最后修改于: 2023-12-03 15:29:42.685000             🧑  作者: Mango

C++ 虚函数问题12

在C++中,虚函数是面向对象编程中的一个重要概念,而问题12是一个围绕虚函数的问题。本文将介绍问题12的背景、解决方案以及相关知识点。

问题背景

考虑以下代码片段:

#include <iostream>
using namespace std;

class A
{
public:
    A()
    {
        cout << "A's constructor called" << endl;
    }
    virtual ~A()
    {
        cout << "A's destructor called" << endl;
    }
};

class B : public A
{
public:
    B()
    {
        cout << "B's constructor called" << endl;
    }
    ~B()
    {
        cout << "B's destructor called" << endl;
    }
};

int main()
{
    A *a = new B();
    delete a;
    return 0;
}

这段代码的预期输出应该是:

A's constructor called
B's constructor called
B's destructor called
A's destructor called

但是,实际输出却是:

A's constructor called
B's constructor called
A's destructor called

这是什么原因呢?

问题分析

仔细观察代码可以发现,基类A的析构函数是虚函数,而派生类B没有重新定义它的析构函数。根据虚函数的机制,如果派生类没有重新定义虚函数,那么它将继承基类中的那个虚函数。因此,在这段代码中,派生类B所继承的A类中的虚函数~A并没有被重载,而是被继承。结果,在删除B对象时,只调用了从A类继承来的~A函数,没有调用B类自己的析构函数。

解决方案

为了解决这个问题,需要在派生类B中重新定义~A函数,即:

class B : public A
{
public:
    B()
    {
        cout << "B's constructor called" << endl;
    }
    ~B()
    {
        cout << "B's destructor called" << endl;
    }
    virtual ~A() override
    {
        cout << "A's destructor called" << endl;
    }
};

这样,当删除B对象时,就会首先调用B类的析构函数,然后调用从A类中继承来的~A函数,问题得以解决。

相关知识点
  • 虚函数机制
  • 虚函数的重载和覆盖
  • 虚析构函数的作用以及用法
总结

问题12是一个旨在考察虚函数机制、覆盖和重载、虚析构函数等面向对象编程基础知识的问题。通过对此问题的分析和解决,在理解虚函数机制以及如何应用虚函数方面可以得到一定的提高。