C+中的奇怪行为+;构造函数\析构函数 我用递归递归地使用C++类构造函数来打印“TRAUTH表”。一切似乎都很正常,直到我决定“为什么不过于递归地使用析构函数?”。当我还实现了用析构函数打印“trauth表”时,我注意到每次控件从对构造函数的递归调用返回时,都会调用析构函数

C+中的奇怪行为+;构造函数\析构函数 我用递归递归地使用C++类构造函数来打印“TRAUTH表”。一切似乎都很正常,直到我决定“为什么不过于递归地使用析构函数?”。当我还实现了用析构函数打印“trauth表”时,我注意到每次控件从对构造函数的递归调用返回时,都会调用析构函数,c++,visual-studio-2010,recursion,constructor,destructor,C++,Visual Studio 2010,Recursion,Constructor,Destructor,输出片段 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 ... ... 班级

输出片段

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
我正在使用VS2010。您可以查看完整的代码及其输出


ADD:我正在尝试使用
int hello\u world::destructor\u调用来计算调用析构函数的总数。我发现打印trauth表算法需要调用
2*(2^MAX)-1
,最后,
destructor\u调用正好等于这个值。然而,当计算输出中的句子
“初始化内的析构函数调用已终止”
时,我们发现它已被输出14次。所以14(初始化中的调用)+15(打印trauth表的自然调用)应该等于29,而
析构函数\u调用
只等于15(好像在初始化时没有调用析构函数!!)

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

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

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

class A {
  A()  { construct(); }
  ~A() { destruct(); }
  void construct(int i=0) { ... construct(i+1); ... }
  void destruct(int i=MAX) { ... destruct(i-1); ... }
};

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

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

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

class A {
  A()  { construct(); }
  ~A() { destruct(); }
  void construct(int i=0) { ... construct(i+1); ... }
  void destruct(int i=MAX) { ... destruct(i-1); ... }
};
你玩火

hello_world::hello_world(str, i + 1);
创建临时对象,然后销毁它…

你玩火

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

创建临时对象,然后销毁它…

确定。但是析构函数呢?它也是递归吗?@sailator:我已经扩展了我的答案,也谈到了析构函数。好的。但是析构函数呢?它也是递归吗?@sailator:我已经扩展了我的答案,也谈到了析构函数。真正的问题是,你为什么要反复调用析构函数?每个对象都可以被销毁一次,而且只能销毁一次。真正的问题是,你为什么要反复调用析构函数?每个对象都可以销毁一次,而且只能销毁一次。这是创建临时对象的正确语法吗?我希望
hello\u world()
没有前缀
hello\u world::
这是创建临时文件的正确语法吗?我希望
hello\u world()
没有前缀
hello\u world::