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

时间:2015-05-22 19:21:04

标签: c++ inheritance destructor

我正在进行一些关于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;
}

答案出现在&#34; 2531&#34; -

我期待答案是&#34; 21&#34; - 理由如下(似乎有缺陷):

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

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

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

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

3 个答案:

答案 0 :(得分:3)

让我们考虑一下构造函数

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.最后,对于B(5)的调用,m_a2将等于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 :(得分:1)

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

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

请参阅:Order of member constructor and destructor calls

答案 2 :(得分:0)

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

所以构造的顺序是:

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

    和破坏如下:

    1. 执行B
    2. 的析构函数体
    3. 销毁m_a2
    4. 销毁m_a1
    5. 销毁基类A
    6. 转换为:

      1. print m_i
      2. 减少m_i
      3. print m_a2
      4. print m_a1
      5. print m_i