1

我正在使用 C++ 类构造函数递归地使用它来打印“真值表”。一切似乎都很正常,直到我决定“为什么不递归地使用析构函数?”。当我还使用析构函数实现打印“真相表”时,我注意到每次控件从对构造函数的递归调用返回时都会调用析构函数。

输出片段

Calling hello_world class constructor...
000
A destructor call within initialization has been terminated
001
A destructor call within initialization has been terminated
A destructor call within initialization has been terminated
010
...
...

班上

#define MAX 3
class hello_world
{
    char *const buf;
    int stack_ptr, destructor_calls;
    bool init;
public:

    // The recursive constructor

    hello_world(char *const &str, int i = 0)
        : buf(str), stack_ptr(0), init(false), destructor_calls(0)
    {
        if (i == MAX)
        {
            buf[i] = '\0';
            cout << buf << endl;
        }
        else
        {
            buf[i] = '0';
            hello_world::hello_world(str, i + 1);
            buf[i] = '1';
            hello_world::hello_world(str, i + 1);
        }
    }

    // The recusive destructor

    ~hello_world()
    {
        ++destructor_calls;
        if (!init) { cerr << "A destructor call within initialization has been terminated" << endl; return; }

        int i = stack_ptr;
        if (i == MAX)
        {
            buf[i] = '\0';
            cout << buf << endl;
        }
        else
        {
            buf[i] = '0';
            ++stack_ptr; // since a destructor cannot take parameters
            hello_world::~hello_world();
            --stack_ptr;
            buf[i] = '1';
            ++stack_ptr;
            hello_world::~hello_world();
            --stack_ptr;

            // Printing total number of calls at final call
            if (i == 0) cout << endl << "\"destrucotr_calls\" = " <<
 destructor_calls << endl;
        }
    }

    void unlock()
    {
        init = true;
    }
}; // end of class hello_world

我正在使用int hello_world::stack_ptr存储当前i参数数量,因为析构函数不能有参数。

我的问题是:为什么每次控件离开对构造函数的递归调用时都会调用析构函数?.

这是我的主要():

void main()
{
    char buf[MAX + 1];
    cout << "Calling hello_world class constructor..." << endl;
    hello_world h(buf);
    h.unlock();
    cout << "Calling hello_world class destructor..." << endl;
}

我正在使用VS2010。您可以在此处查看完整的代码及其输出

添加:我正在尝试使用 . 计算调用析构函数的总数int hello_world::destructor_calls。我发现打印真值表算法需要2 * (2^MAX) - 1调用,最后destructor_calls完全等于这个值。但是,当计算输出中的句子"A destructor call within initialization has been terminated"时,我们发现它已经输出了 14 次。所以 14(初始化中的调用)+ 15(打印真值表的自然调用)应该等于 29,而destructor_calls仅等于 15(好像在初始化时没有调用析构函数!!)

4

2 回答 2

3

没有递归构造函数之类的东西。看起来像递归的东西实际上是创建一个新的临时对象。

可以直接调用析构函数,但是如果对同一个对象调用两次析构函数,则会得到未定义的行为,因此不能递归调用它。

您需要做的是在构造函数或析构函数中调用另一个成员函数。然后,您可以使这些其他函数递归:

class A {
  A()  { construct(); }
  ~A() { destruct(); }
  void construct(int i=0) { ... construct(i+1); ... }
  void destruct(int i=MAX) { ... destruct(i-1); ... }
};
于 2012-09-09T14:31:15.197 回答
2

你玩火...

hello_world::hello_world(str, i + 1);

创建临时对象,然后将其销毁...

于 2012-09-09T14:31:59.793 回答