9

「this」キーワードが使用された場合、システムはどのように使用するかを判断しますか?

最近、インタビューでこんな質問をされました。これについて考えたことがなかったので、システムは制御の流れが現在のコンテキストを認識し、これの代わりに使用するオブジェクトを決定すると答えました。インタビュアーは満足していないようで、次の質問に移りました。

インタビュアーが何を聞きたかったのか、答えは何だったのか誰か教えてもらえますか? (これはさまざまな方法で解釈できると思います。したがって、誰かが指摘しない限り、これをwikiとして保持します..)

4

11 に答える 11

12

thisキーワードは、現在のオブジェクトへのポインターです。クラスのすべての非静的メンバー関数は、this ポインターにアクセスできます。

通常、現在のオブジェクトへのポインターは、レジスター (通常は ECX) を使用して、コンパイラーによって非静的メンバー関数で使用可能になります。thisそのため、非静的メンバー関数を記述すると、コンパイラはその呼び出しを ECX からのアドレスの読み込みに変換します。

この簡単な例を確認してください。

で;
t.Test();
004114DE lea ecx,[t]
004114E1 呼び出し std::operator > (41125Dh)

非静的メンバ関数を呼び出す前にTest()、コンパイラはレジスタ ECX に [t] をロードします (変数 t のアドレス - thisTest メソッド内になります)。

004114DE lea ecx,[t]

関数内では、ecx を使用して現在のオブジェクト インスタンスのアドレスを取得できます。

于 2009-08-21T15:07:28.913 に答える
9

thisオブジェクトのすべてのメソッドの隠しパラメーターであり、インスタンス ポインターのコピーが含まれています。

于 2009-08-21T14:53:44.053 に答える
2

このクラスを検討してください

class A {
private:
    int data;
public:
    void SetData(int arg) {
        this->data = arg;
    }
}

そして、SetData()を呼び出すこのコード:

A objA;
objA.SetData(1);

上記のコードをコンパイルすると、コンパイラはメンバー関数に対してこれと同等の何かを発行します。

void SetData(A* this, int arg) {
     this->data = arg;
}

そして、呼び出し元のコードは次のようなものに変換されます。

A objA;
SetData(&objA, 1);

これが意味するのは、コンパイル時のことです。

  1. メンバー関数は、単純なグローバル関数に変換されます。

  2. メンバー関数が「属する」クラスインスタンスは、最初の引数として単純に渡されます(つまり、そのアドレスが渡されます)。

したがって、結論として、コードでこのポインターと呼んでいるものは、関数の最初の引数であるだけです。これは、「システムが」「this」ポインタを介してアクセスするオブジェクトを「認識する」方法です。

上記の例はC++のものです。CLRやJITtingなどを少し忘れても、C#で発生することは概念的に同じです。

于 2009-08-21T15:17:49.723 に答える
1

実行時に「this」は現在のオブジェクトへのポインターに解決されるため、「システム」はそのオブジェクトのそれぞれのメソッドを呼び出すことができます。

于 2009-08-21T14:54:03.960 に答える
1

コンパイラは、コンパイル時にその参照を正しく解決します。彼らがこれを行うために使用するいくつかのテクニックについて詳しく知りたい場合は、この本で知っておくべきことがすべてわかります:
http://en.wikipedia.org/wiki/Compilers:_Principles,_Techniques,_and_Tools
ドラゴンブック

于 2009-08-21T15:21:31.340 に答える
1

「現在のクラスのインスタンスへの参照です」と答えたでしょう。

ダン

于 2009-08-21T14:54:46.283 に答える
0

c では、 this ポインターは、クラスへの目に見えないポインター引数です。

したがって、本質的に、クラス メソッドへの最初の引数は、クラス自体へのポインターです。this を使用して参照します。

于 2009-08-21T14:54:27.190 に答える
0

Shematicaly コンパイラはそのようなコードを変換します:

pObject->someMethod(A,B,C)

「someMethod」が仮想でない場合、そのようなコードに:

someMethod(pObject,A,B,C) 

または、「someMethod」が仮想の場合、そのようなコードに:

(*pObject->vtable[someMethodIndex]) (pObject, A,B,C)

そして、「this」キーワードを配置するすべての場所で、代わりに最初のパラメーターが使用されます。

もちろん、コンパイラは最初の引数を削除して最適化/簡素化し、CPU レジスタ (通常は esx) を使用してオブジェクトのアドレスを格納する場合があります。

于 2009-08-21T15:20:11.250 に答える
0

私の答えは、「誰が気にしますか? それは知っています。さらに詳細を調べる必要がある場合は、Google で検索します」でした。

「this」を使用した場合の効果は明ら​​かであり、これは確かに重要なことです。プログラミング タスクの 99% について、それが内部でどのように解決されるかの詳細は些細なことだと思っていたでしょう。

于 2009-08-21T15:23:55.487 に答える