アセンブリから見たc++のデフォルトの解析関数
5697 ワード
c++では、クラスに構造関数が提供されていない場合、コンパイラはこのクラスにデフォルトの構造関数を提供します.コンストラクタの機能はコンストラクタとは逆であるため、デフォルトのコンストラクタと同様に、コンパイラは不要なデフォルトのコンストラクタと不要なコンストラクタを提供します.両方の解析は同じです(デフォルトのコンストラクタ解析では「アセンブリから見たc++のデフォルト構造関数」を参照).また、コンパイラは、最初の1つだけが異なるデフォルト構造関数と同様に、不要でないデフォルト構造関数を提供します.
1クラスに虚メンバー関数(または継承されたベースクラスに虚メンバー関数が含まれている場合も)が含まれている場合、コンパイラは不要なデフォルトの構造関数を提供しません.
c++ソースコードは以下の通りです.
次はmain関数のアセンブリコードです.
アセンブリコードから、クラスXにはダミーメンバー関数が含まれているにもかかわらず、コンパイラは呼び出しの構造関数を表示していないことがわかります.ただし、コンパイラはvptrポインタを初期化するため、デフォルトのコンストラクション関数呼び出しを提供していることがわかります.
2このクラスはダミーベースクラスから継承されます
まずc++ソースコードを見てください.
ダミーベースクラスXとサブクラスYは、構造関数を定義していません.次はmain関数の符号化です.
アセンブリから分かるように,コンパイラもクラスYに構造関数を提供していない.
3クラスは1つのベースクラスから継承され、ベースクラスにはカスタム構造関数が含まれています(ベースクラスにカスタム構造関数がない場合、コンパイラが不要ではないデフォルトの構造関数を提供する場合もあります.つまり、ベースクラスに構造関数が含まれている限り、この構造関数が自己定義されているか、コンパイラが提供する不要ではないデフォルトの構造関数であるかにかかわらず、どちらでもよいということです).
4クラスにはメンバーオブジェクトが含まれています.このメンバー・オブジェクトのカスタム構造関数(メンバー・オブジェクトにカスタム構造関数がない場合、コンパイラが不要でないデフォルトの構造関数を提供する場合も同様です.つまり、メンバー変数に構造関数が含まれている限り、この構造関数がカスタムであるか、コンパイラが提供する不要でないデフォルトの構造関数であるかにかかわらず、メンバー変数に構造関数が含まれている場合でも構いません).
また、コンパイラが提供するデフォルトの解析関数では、オブジェクトに含まれるリソースは、不要でも不要でも自動的に消去されません.
1クラスに虚メンバー関数(または継承されたベースクラスに虚メンバー関数が含まれている場合も)が含まれている場合、コンパイラは不要なデフォルトの構造関数を提供しません.
c++ソースコードは以下の通りです.
class X {
private:
int i;
public:
virtual void set(int ii) {
i == ii;
}
};
int main() {
X x;
}
次はmain関数のアセンブリコードです.
_main PROC
; 9 : int main() {
push ebp
mov ebp, esp
sub esp, 8
; 10 : X x;
lea ecx, DWORD PTR _x$[ebp]; x ,
call ??0X@@QAE@XZ;
; 11 : }
xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP
アセンブリコードから、クラスXにはダミーメンバー関数が含まれているにもかかわらず、コンパイラは呼び出しの構造関数を表示していないことがわかります.ただし、コンパイラはvptrポインタを初期化するため、デフォルトのコンストラクション関数呼び出しを提供していることがわかります.
2このクラスはダミーベースクラスから継承されます
まずc++ソースコードを見てください.
class X {
private:
int i;
};
class Y : public virtual X {
private:
int i;
};
int main() {
Y y;
}
ダミーベースクラスXとサブクラスYは、構造関数を定義していません.次はmain関数の符号化です.
_main PROC
; 11 : int main() {
push ebp
mov ebp, esp
sub esp, 12 ; 0000000cH
; 12 : Y y;
push 1
lea ecx, DWORD PTR _y$[ebp]
call ??0Y@@QAE@XZ; y
; 13 : }
xor eax, eax
mov esp, ebp
pop ebp
ret 0
_main ENDP
アセンブリから分かるように,コンパイラもクラスYに構造関数を提供していない.
3クラスは1つのベースクラスから継承され、ベースクラスにはカスタム構造関数が含まれています(ベースクラスにカスタム構造関数がない場合、コンパイラが不要ではないデフォルトの構造関数を提供する場合もあります.つまり、ベースクラスに構造関数が含まれている限り、この構造関数が自己定義されているか、コンパイラが提供する不要ではないデフォルトの構造関数であるかにかかわらず、どちらでもよいということです).
4クラスにはメンバーオブジェクトが含まれています.このメンバー・オブジェクトのカスタム構造関数(メンバー・オブジェクトにカスタム構造関数がない場合、コンパイラが不要でないデフォルトの構造関数を提供する場合も同様です.つまり、メンバー変数に構造関数が含まれている限り、この構造関数がカスタムであるか、コンパイラが提供する不要でないデフォルトの構造関数であるかにかかわらず、メンバー変数に構造関数が含まれている場合でも構いません).
また、コンパイラが提供するデフォルトの解析関数では、オブジェクトに含まれるリソースは、不要でも不要でも自動的に消去されません.