1

私の知る限り、C ++では、同じクラスの関数のメンバー内で別のメンバー関数を呼び出すには、暗黙的であるため、「this」プレフィックスは必要ありません。ただし、関数ポインターを使用する特定のケースでは、コンパイラーはそれを必要とします。次のコードは、func ポインターを介した呼び出しに "this" プレフィックスを含めた場合にのみ正しくコンパイルされます -

関数ポインターが使用されている場合、コンパイラーは同じクラスのメンバー func を指していると推測できますか?

class FooBar 
{
private: 
    int foo;

public:  

    FooBar()
    {
        foo = 100;
    }

    int GetDiff(int bar)
    {
        return abs(foo - bar);
    }

    typedef int(FooBar::*MyFuncPtr)(int); 

    void FooBar::Bar()
    {       
        MyFuncPtr f = &FooBar::GetDiff;
        (this->*f)(10);
        GetDiff(10);
    }

};
4

5 に答える 5

6

メンバー関数ポインター (関数ポインターと同じではない) はバインドされておらず、別のオブジェクトで使用できるため、必須です。

(this->*f)(10);
(foo.*f)(10);
// etc.
于 2012-06-26T17:10:32.830 に答える
2

インスタンス メンバー関数を呼び出すと、 this ポインターが暗黙的に関数パラメーターに配置されます。thisしたがって、関数ポインタを介してその関数を呼び出すときにも指定する必要があります。

fはクラスのメンバーではなく、ローカル変数です。代わりに別のインスタンス ポインターを指定することもthisできるため、コンパイラーはそれを推測できません。メンバー関数ポインターについては、クラス メンバー変数と同じです。

于 2012-06-26T17:11:34.157 に答える
1

簡単な質問は、それは言語設計の問題であり、言語はこのように設計されているということです。

メンバー関数内で、コンパイラが識別子に遭遇したときに一般的な構文を緩和するために、コンパイラはこのクラス (および引数の ADL) から始まるルックアップを実行し、ルックアップでこの型 (または基本型) の場合、コンパイラが挿入this->します (つまりoperator->thisポインターに適用されます)。

メンバーへのポインターの場合、プロセスはまったく異なります。ポインター (実際にはポインターではありませんが、引数のため) はルックアップによって検出されますが、呼び出されるオブジェクトを提供し、適切な演算子を使用するのはユーザーの責任です (.*メンバーへのポインターを呼び出すため)。参照、または->*ポインターでメンバーを呼び出すため)。

呼び出される演算子が異なり、プロセスがまったく異なることに注意してください (ルックアップでメンバーが見つかる場合もあれば、たまたまメンバーへのポインターである変数が見つかる場合もあります)。ただし、最も重要な部分は次のとおりです。メンバーへのポインターを呼び出すことは十分にまれであり、それらを呼び出すことthisはさらに少ないため、小さなユースケースの構文の免除を保証するものではありません。

于 2012-06-26T18:04:05.143 に答える
0

fのメンバーではありませんFooBar。したがってf、のインスタンスを呼び出す場合はFooBar、どのインスタンスを呼び出す必要があります。

あなたの例でfは、FooBarのメンバーが含まれていますが、コンパイラはそれを認識していません。

于 2012-06-26T17:09:46.047 に答える
0

これは、ユーザーが見ていないときに C++ ランタイムがクラスを処理する方法が原因で発生します。基本的に、関数ポインターをインスタンスに格納するのは非効率的であるため、コンパイラーは、定義したメンバー関数と同じアリティを持ち、実行時に渡される this ポインターを取得する関数ポインターを持つクラス固有のテーブルを構築します (AFAIK visualc は、 ecx 経由のポインター、GCC で何が起こるかは完全にはわかりません)

だから基本的にあなたがするとき

instance->foo(10);

パラメーター 10 を指定して関数 foo を呼び出し、(インスタンス) を this ポインターとして渡すようにランタイムに指示しています。そのため、呼び出す必要があるオブジェクトを具体的に指定する必要があります。

于 2012-06-26T17:26:50.577 に答える