C ++クラスのコンストラクター関数を再帰的に使用して、「trauthテーブル」を出力して遊んでいました。「デストラクタを再帰的に使用しないのはなぜですか」と判断するまでは、すべてが正常であるように見えました。デストラクタを使用して「trauthテーブル」の印刷も実装したとき、コントロールがコンストラクタへのrecurisve呼び出しから戻るたびにデストラクタが呼び出されていることに気付きました。
出力スニペット
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のみに等しい必要があります(初期化時にデストラクタが呼び出されていないかのように!!)