使用析构函数时清除成员变量

问题描述 投票:0回答:3

我正在做一些关于 C++ 的在线测验,下面是我遇到的问题

http://www.interqiew.com/ask?ta=tqcpp01&qn=3

class A
{
public:
    A(int n = 2) : m_i(n) { }

    ~A() { std::cout << m_i; }

protected:
    int m_i;
};

class B
    : public A
{
public:
    B(int n) : m_a1(m_i + 1), m_a2(n) { }

public:
    ~B()
    {
        std::cout << m_i;
        --m_i;
    }

private:
    A m_a1;
    A m_a2;
};

int main()
{
    { B b(5); }

    std::cout << std::endl;

    return 0;
}

答案是“2531” -

我期待答案是“21” - 基本原理如下(这似乎是错误的):

对象 B 使用三个成员变量创建,起始值为 2 - 253

因此,当析构函数被调用时,将以相反的顺序删除。

对于这种情况,析构函数将调用继承部分 - 我们打印 2 我们递减值并转到 1,然后打印基数,同时删除 - 所以回答 21

变量 m_a2 和 m_a1 是如何打印的 - 无法理解。 它还在基础部分(即 A 类)中打印(值 53)

c++ inheritance destructor
3个回答
4
投票

让我们考虑一下构造函数:

B(int n) : m_a1(m_i + 1), m_a2(n) { }

相当于:

B(int n) : A(), m_a1(m_i + 1), m_a2(n) { }

所以首先 m_i 由构造函数 A 的默认参数初始化,等于 2。然后 m_a1 将由 m_i + 1 初始化,即等于 3。最后 m_a2 将等于5 表示 B( 5 ) 的调用

然后当 B 的析构函数被调用时,它输出:

std::cout << m_i;

即:

2

然后减少 m_i:

--m_i;

数据成员的析构函数以与其构造相反的顺序调用。所以首先会调用 m_a2 的析构函数,它会输出:

5

然后会调用m_a1的析构函数,输出:

3

最后将调用基类的析构函数,输出:

1

所以你会得到:

2531

至于你的问题,A 的析构函数被调用三次:两次是在类 B 的数据成员 m_a1 和 m_a2 被销毁时(因为它们具有类型类 A)以及调用基类构造函数时。


1
投票

2531
是正确答案。调用析构函数的顺序始终与调用构造函数的顺序相反。

  • 2
    - B
  • 的析构函数
  • 5
    ,
    3
    - 类字段的析构函数,其顺序与初始化顺序相反
  • 1
    - 超类的析构函数

参见:成员构造函数和析构函数调用的顺序


0
投票

我相信成员对象的析构函数都是在指定的析构函数之后调用的,与它们在类中的声明顺序相反,然后调用基对象的析构函数。

所以构建的顺序是这样的:

  1. 构造基类
    A
    ,默认值为
    m_i
    2
  2. 根据初始化的
    B
    构造
    m_a1
    成员
    m_i
  3. 的值
  4. 使用参数 5 的值构造
    B
    成员
    m_a2

销毁如下:

  1. 执行
    B
  2. 的析构函数体
  3. 摧毁
    m_a2
  4. 摧毁
    m_a1
  5. 析构基类
    A

翻译为:

  1. 打印
    m_i
  2. 减少
    m_i
  3. 打印
    m_a2
  4. 打印
    m_a1
  5. 打印
    m_i
© www.soinside.com 2019 - 2024. All rights reserved.