多个析构函数调用

时间:2015-05-29 17:39:51

标签: c++ c++11

我运行了以下代码..

#include <iostream>
using namespace std;

class Base
{
protected:
    int count=0;
public:
    Base() { cout << "Constructor called" << endl; }
    ~Base() { cout << "Destructor called" << endl; }
    int getCount() {cout << "The count value is " << count << endl;}
    Base operator ++ (int) {count++;  cout << "Postfix increment called" << endl;}
    Base operator ++ () {count++;  cout << "Prefix increment called" << endl;}
};

class Derived : public Base
{
public:
    Base operator --(int)  {count--;  cout << "Postfix decrement called" << endl;}
};

int main()
{
    Derived A;
    A++;
    ++A;
    A--;
    return 0;
}

我得到的结果是

Constructor called
Postfix increment called
Destructor called
Prefix increment called
Destructor called
Postfix decrement called
Destructor called
Destructor called

我的问题是为什么析构函数会这么多次调用?

4 个答案:

答案 0 :(得分:2)

首先是所有这些运营商

Base operator ++ (int) {count++;  cout << "Postfix increment called" << endl;}
Base operator ++ () {count++;  cout << "Prefix increment called" << endl;}
Base operator --(int)  {count--;  cout << "Postfix decrement called" << endl;}

无效,因为虽然返回类型不是无效,但它们不返回任何内容。你应该写例如

Base operator ++ (int) 
{
    count++;  
    cout << "Postfix increment called" << endl;
    return *this;
}

否则程序有不确定的行为。

由于运算符具有返回类型Base,因此编译器会调用析构函数以获取运算符必须返回的临时对象。

所有这三个表达

A++;
++A;
A--;

实际上是临时对象。

答案 1 :(得分:2)

从概念上讲,每个运算符都会向调用者返回类型为Base的临时对象。每次操作员调用后,该临时对象都会被销毁。这种破坏正是您在实验中观察到的。

但是,您忘记将return语句包含在运算符定义中。因此,您的代码具有未定义的行为。

答案 2 :(得分:1)

当变量作为非引用变量传递时,编译器使用set copy-constructor创建变量,并在其范围结束后销毁它。

要解决此问题,您可以将变量作为参考传递。

答案 3 :(得分:0)

您的运营商返回Base。由于您没有捕获Base,因此它会在表达式的末尾被销毁。由于你有三个表达式,你得到三个析构函数调用。