C++クラスのthisポインタまとめ

4389 ワード

初めてthisを使うのは便利な感じで、使っているうちに少しぼんやりしていましたが、次はthisポインタをまとめてみましょう.
1.thisとは
まずclassの意味を理解するには,classはint,charのようにユーザがカスタマイズしたタイプとして理解すべきである.(int charのようなbuild-inタイプよりも複雑ですが、まず同じタイプであることを理解してください).このタイプでは、int x、myclass myなどの変数を宣言できます.これにより、変数xがintタイプを有するように、変数myはmyclassタイプを有する.これを理解すれば、thisを説明しやすくなります.myのthisはmyを指すポインタです.もう1つの変数myclass mzがある場合、mzのthisはmzを指すポインタであり、その解参照*thisはmyclassタイプの変数であるべきである.a.sum()などのメンバー関数が呼び出されると、sum関数はステルスパラメータthisによってaにアクセスできるので、thisは呼び出されたオブジェクトが呼び出されたオブジェクトにアクセスするツールであり、thisが呼び出されたオブジェクトを指すと理解できる.デフォルトでは、thisのタイプはクラスタイプの非常に大量の定数ポインタを指すため、デフォルトでは初期化時にthisを定数オブジェクトにバインドすることはできません.そのため、パラメータリストの後ろにconstを加えてthisの属性を変更し、定数オブジェクトを指すことができ、関数の柔軟性を高めることができます.このメンバー関数は定数メンバー関数とも呼ばれます.
とにかくthisを使うときは、ぼんやりしていたらint*pを考えて最初のポインタに戻ると、はっと悟るかもしれません.
thisポインタ1、同じタイプのオブジェクトはそれぞれ独立したメンバーインスタンスを持ち、互いにメンバー関数を2つ共有し、メンバー関数が誰が呼び出しているかをどのように知っています.2、コンパイラは、どのオブジェクトが呼び出されているかをメンバー関数に知らせ、オブジェクトのメンバーに正確にアクセスするために、呼び出されたオブジェクトへのポインタである見えないパラメータをメンバー関数ごとに自動的に追加します(this).3、クラス内のすべてのメンバー関数には、構造、プロファイル、コピー構造などを含むthisポインタがあります.ただし、この構造では作成中のオブジェクトを指します.4、thisポインタはデフォルトでは非表示です(メンバー関数でメンバー変数にアクセスすると自動的に加算されます)が、使用を表示することもできます.5、使用状況this a、メンバー変数とパラメータbを区別し、オブジェクトを戻り値として他のオブジェクトと対話する.
d:クラスの非静的メンバー関数でクラスオブジェクト自体を返す場合はreturn*thisを直接使用します.
e:もう1つの場合、パラメータがメンバー変数名と同じである場合、this->n=n(n=nとは書けない).
f:class定義でタイプ変数自体を使用する場合、変数名が分からないのでthisのようなポインタで変数自体を使用します. 
コードを見てみましょう.
#include 
#include 

using namespace std;

class Student
{
	char name[20];
	char sex;
	short age;
public:
	Student(const char* name,char sex,short age)
	{
		strcpy(this->name,name);
		this->sex = sex;
		this->age = age;
	}
	void show(void)
	{
		cout << this->name <age<< endl;
	}
};

int main()
{
	Student s("haha",'m',3);
	s.show();
}

クラスでは、コンストラクション関数はクラスメンバー名と同じパラメータを使用しています.これはthisポインタを使用すると、この競合がうまく解決されます.実際には、C++の初期化リストも使用できます.
2.よくある困惑問題
A.thisポインタはいつ作成されますか?
thisは、メンバー関数の実行開始前に構築され、メンバーの実行終了後に消去されます.しかしclassやstructに方法がなければ,それらは構造関数がなく,Cのstructとしてしか使用できない.TYPE xxで定義すると、スタックにメモリが割り当てられ、このときthisポインタの値がこのメモリのアドレスになります.new方式でオブジェクトを作成すると、スタックにメモリを割り当て、newオペレータはeaxで割り当てられたアドレスを返し、ポインタ変数に設定します.その後、コンストラクション関数(コンストラクション関数があれば)を呼び出します.このメモリブロックのアドレスをecxに渡します.その後、コンストラクション関数の中でどのように処理するかは、上記の回答を見てください.
B.thisポインタはどこに保管されていますか.スタック、スタック、グローバル変数、またはその他?
このポインタはコンパイラによって配置位置が異なります.スタックかもしれないし、レジスタかもしれないし、グローバル変数もあります.アセンブリレベルでは、1つの値は、即時数、レジスタ値、メモリ変数値の3つの形式でのみ表示されます.レジスタではなくメモリに格納され、高度な言語変数に対応するものではありません.
C.thisポインタはクラス内の関数をどのように伝達しますか?バインド?それとも関数パラメータの最初のパラメータがthisポインタですか?では、thisポインタはどのようにして「クラスインスタンス後の関数」を見つけますか?
ほとんどのコンパイラはecxレジスタを介してthisポインタを渡します.実際、これも潜在的なルールです.一般的に、異なるコンパイラは一貫したパラメータルールに従います.そうしないと、異なるコンパイラによって生成されたobjは一致しません.callの前に、コンパイラは対応するオブジェクトアドレスをeaxに配置します.これは関数パラメータの最初のパラメータによって伝達されます.thisポインタは呼び出す前に生成され、「クラスインスタンス後関数」については、この言い方はありません.クラスがインスタンス化されると、クラス内の変数空間のみが割り当てられ、関数に空間は割り当てられません.クラスの関数定義が完了してから、そこにあります.走ることはありません.
D.thisポインタはクラスの変数にどのようにアクセスしますか?
クラスではなく構造体であれば、構造ポインタで構造内の変数にアクセスするにはどうすればいいのでしょうか.この点が分かれば、この問題は簡単に理解できます.C++では、クラスと構造は1つの違いしかありません.クラスのメンバーのデフォルトはprivateであり、構造はpublicです.これはクラスのポインタで、構造に変えると、thisは構造のポインタです.
E.オブジェクトを取得してから、このポインタを使用することができます.オブジェクトthisポインタの位置を知っていれば、直接使用できますか?
thisポインタはメンバー関数でのみ定義されます.したがって、オブジェクトを取得した後も、このポインタをオブジェクトで使用することはできません.したがって、オブジェクトのthisポインタの位置を知ることはできません(メンバー関数にのみthisポインタの位置があります).もちろん、メンバー関数では、thisポインタの位置を知ることができます(&thisで得ることができます)、直接使用することもできます.
F.各クラスをコンパイルした後、クラス内の関数テーブルを作成して関数ポインタを保存し、関数を呼び出すことができますか?
通常のクラス関数(メンバー関数でも静的関数でも)では、関数ポインタを保存する関数テーブルは作成されません.虚関数のみが関数テーブルに配置されます.ただし、虚関数であっても、コンパイラが呼び出した関数がどの関数であるかを明確に知ることができれば、コンパイラは関数テーブルのポインタで間接的に呼び出されるのではなく、その関数を直接呼び出すことになります.
G:thisは値を付けることができますか.
C++では、thisポインタは「X*const this」と暗黙的に宣言され、これはthisポインタに値を割り当てることができないことを意味します.Xクラスのconstメンバー関数では、thisポインタのタイプは、const X*constです.これは、thisポインタが指すオブジェクトが変更できないことを示しています(つまり、このオブジェクトのデータメンバーに値を割り当てる操作はできません).これは通常の変数ではないため、thisのアドレスを取得することはできませんが、コンパイラはできます.
注意***************************************************************************************************
クラス内のメンバー関数がクラスメンバーを実際に使用する場合、コンパイラは自動的にメンバー関数にthisポインタを渡し、メンバー関数がクラス内の他のメンバーに自由にアクセスできるようにするため、ここでは関数マッチングの問題に関連しています.typedefを使用して関数ポインタを定義した場合は、staticでクラスメンバー関数を静的メンバー関数に宣言することに注意してください.そうでないと、コンパイラは自動的にメンバー関数にthisポインタを付け、typedefの関数に一致しない可能性があります.