「this」をコンストラクター内から関数に渡しますか?
-
22-07-2019 - |
質問
「これ」を渡すことはできますかクラスコンストラクター内から関数をポインターとして使用し、コンストラクターが戻る前にオブジェクトのメンバーを指すために使用しますか?
アクセスするメンバーが関数呼び出しの前に適切に初期化されている限り、これを行うことは安全ですか?
例:
#include <iostream>
class Stuff
{
public:
static void print_number(void *param)
{
std::cout << reinterpret_cast<Stuff*>(param)->number;
}
int number;
Stuff(int number_)
: number(number_)
{
print_number(this);
}
};
void main() {
Stuff stuff(12345);
}
これはうまくいかないと思ったが、そうだ。この標準的な動作ですか、それとも未定義の動作ですか?
解決
C ++でオブジェクトをインスタンス化すると、コンストラクター内のコードが最後に実行されます。スーパークラスの初期化、スーパークラスコンストラクターの実行、メモリ割り当てなど、他のすべての初期化は事前に行われます。コンストラクター内のコードは、オブジェクトが構築されると、実際には追加の初期化を実行するだけです。そのため、「this」を使用することは完全に有効です。クラスのコンストラクターのポインターと、それが完全に構築されたオブジェクトを指すと仮定します。
もちろん、コンストラクターコードでまだ初期化していない場合は、初期化されていないメンバー変数に注意する必要があります。
他のヒント
このこちらに対する適切な答えを見つけることができます。 (C ++ FAQ)。
すべての継承されたメンバーと呼び出し元クラスのメンバーは、コンストラクターのコード実行の開始時に構築されていることが保証されているため、その中で安全に参照できます。
主な落とし穴は、 this
で仮想関数を呼び出さないことです。私がこれを試したほとんどの場合、それは基本クラスの関数を呼び出すことになりますが、標準は結果が未定義であると言っていると思います。
提示されたコードの補足として、代わりに void *
をテンプレート化します:
class Stuff
{
public:
template <typename T>
static void print_number(const T& t)
{
std::cout << t.number;
}
int number;
Stuff(int number_)
: number(number_)
{
print_number(*this);
}
};
t
の型に number
メンバーがない場合、コンパイルエラーが発生します。
アンディ、規格の未定義部分については間違っていると思います。
コンストラクターにいるとき、&quot; this&quot;は、作成するオブジェクトのベースクラスであるタイプへのポインタです。つまり、ベースクラスで部分的に実装された仮想関数が呼び出され、仮想テーブルのポインタが呼び出されます。従う。
C ++ Faq Lite の詳細...