質問

「これ」を渡すことはできますかクラスコンストラクター内から関数をポインターとして使用し、コンストラクターが戻る前にオブジェクトのメンバーを指すために使用しますか?

アクセスするメンバーが関数呼び出しの前に適切に初期化されている限り、これを行うことは安全ですか?

例:

#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 の詳細...

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top