簡體   English   中英

C ++構造函數\\析構函數中的奇怪行為

[英]Strange behavior in C++ constructor\destructor

我正在通過遞歸使用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參數的當前數量,因為析構函數不能具有參數。

我的問題是: 為什么每次控件離開對構造函數的遞歸調用時都調用析構函數?

這是我的main():

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的調用析構函數的總數。 我發現打印trauth表算法需要2 * (2^MAX) - 1調用,最后, destructor_calls於此值。 但是,在輸出中計算句子"A destructor call within initialization has been terminated"時,我們發現它已被輸出14次。 因此14(初始化中的調用)+ 15(打印trauth表的自然調用)應該等於29,而destructor_calls僅等於15(好像在初始化時未調用析構函數!)

沒有遞歸構造函數。 看起來像遞歸實際上是在創建一個新的臨時對象。

可以直接調用析構函數,但是如果您在同一對象上兩次調用析構函數,則會得到未定義的行為,因此無法遞歸調用它。

您需要做的是在構造函數或析構函數內調用另一個成員函數。 然后,您可以使這些其他函數遞歸:

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);

創建臨時對象然后銷毀它...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM