Destructor 调用究竟是如何进行的
How exactly are Destructor calls made
我想知道在 C++ 中,构造函数或析构函数究竟是如何被调用的?我对 OS 观点特别感兴趣。我也对我们 运行 android 用 java 编写的应用程序的情况感兴趣,我们想要获取有关用户会话的信息。我们可以使用 conatructor 设置会话开始时间和 destr 设置会话结束时间并将数据保存在数据库中吗?实际上 OS 是否处理析构函数调用或其他?提前致谢!
我不熟悉Java如何处理构造函数和析构函数(Java涉及虚拟机层),但我会尝试从cpp的角度回答这个问题。
对你的问题的简短回答:OS不参与构造函数或析构函数(除非有堆分配、系统调用...)。编译器在生成机器码时会在正确的位置插入对构造函数和析构函数的调用。
简单程序如下:
class A{
int* i;
public:
A() { i = new int; }
~A() { delete i; }
};
int main() {
A a;
}
让我们检查一下编译器使用 objdump
:
发出的汇编代码
00000000004006a6 <main>:
4006a6: 55 push %rbp
4006a7: 48 89 e5 mov %rsp,%rbp
4006aa: 48 83 ec 10 sub [=11=]x10,%rsp
4006ae: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
4006b5: 00 00
4006b7: 48 89 45 f8 mov %rax,-0x8(%rbp)
4006bb: 31 c0 xor %eax,%eax
4006bd: 48 8d 45 f0 lea -0x10(%rbp),%rax
4006c1: 48 89 c7 mov %rax,%rdi
4006c4: e8 27 00 00 00 callq 4006f0 <_ZN1AC1Ev>
4006c9: 48 8d 45 f0 lea -0x10(%rbp),%rax
4006cd: 48 89 c7 mov %rax,%rdi
4006d0: e8 3f 00 00 00 callq 400714 <_ZN1AD1Ev>
4006d5: b8 00 00 00 00 mov [=11=]x0,%eax
4006da: 48 8b 55 f8 mov -0x8(%rbp),%rdx
4006de: 64 48 33 14 25 28 00 xor %fs:0x28,%rdx
4006e5: 00 00
4006e7: 74 05 je 4006ee <main+0x48>
4006e9: e8 92 fe ff ff callq 400580 <__stack_chk_fail@plt>
4006ee: c9 leaveq
4006ef: c3 retq
请注意,根据底层架构和编译器,您的输出可能与我的不同,但结构通常应该相同。
您可以看到编译器自动生成对构造函数 callq 400714 <_ZN1AD1Ev>
和析构函数 callq 400714 <_ZN1AD1Ev>
的调用。构造函数的汇编代码是:
00000000004006f0 <_ZN1AC1Ev>:
4006f0: 55 push %rbp
4006f1: 48 89 e5 mov %rsp,%rbp
4006f4: 48 83 ec 10 sub [=12=]x10,%rsp
4006f8: 48 89 7d f8 mov %rdi,-0x8(%rbp)
4006fc: bf 04 00 00 00 mov [=12=]x4,%edi
400701: e8 8a fe ff ff callq 400590 <_Znwm@plt>
400706: 48 89 c2 mov %rax,%rdx
400709: 48 8b 45 f8 mov -0x8(%rbp),%rax
40070d: 48 89 10 mov %rdx,(%rax)
400710: 90 nop
400711: c9 leaveq
400712: c3 retq
400713: 90 nop
析构函数的程序集:
0000000000400714 <_ZN1AD1Ev>:
400714: 55 push %rbp
400715: 48 89 e5 mov %rsp,%rbp
400718: 48 83 ec 10 sub [=13=]x10,%rsp
40071c: 48 89 7d f8 mov %rdi,-0x8(%rbp)
400720: 48 8b 45 f8 mov -0x8(%rbp),%rax
400724: 48 8b 00 mov (%rax),%rax
400727: 48 89 c7 mov %rax,%rdi
40072a: e8 31 fe ff ff callq 400560 <_ZdlPv@plt>
40072f: 90 nop
400730: c9 leaveq
400731: c3 retq
400732: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
400739: 00 00 00
40073c: 0f 1f 40 00 nopl 0x0(%rax)
我想知道在 C++ 中,构造函数或析构函数究竟是如何被调用的?我对 OS 观点特别感兴趣。我也对我们 运行 android 用 java 编写的应用程序的情况感兴趣,我们想要获取有关用户会话的信息。我们可以使用 conatructor 设置会话开始时间和 destr 设置会话结束时间并将数据保存在数据库中吗?实际上 OS 是否处理析构函数调用或其他?提前致谢!
我不熟悉Java如何处理构造函数和析构函数(Java涉及虚拟机层),但我会尝试从cpp的角度回答这个问题。
对你的问题的简短回答:OS不参与构造函数或析构函数(除非有堆分配、系统调用...)。编译器在生成机器码时会在正确的位置插入对构造函数和析构函数的调用。
简单程序如下:
class A{
int* i;
public:
A() { i = new int; }
~A() { delete i; }
};
int main() {
A a;
}
让我们检查一下编译器使用 objdump
:
00000000004006a6 <main>:
4006a6: 55 push %rbp
4006a7: 48 89 e5 mov %rsp,%rbp
4006aa: 48 83 ec 10 sub [=11=]x10,%rsp
4006ae: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
4006b5: 00 00
4006b7: 48 89 45 f8 mov %rax,-0x8(%rbp)
4006bb: 31 c0 xor %eax,%eax
4006bd: 48 8d 45 f0 lea -0x10(%rbp),%rax
4006c1: 48 89 c7 mov %rax,%rdi
4006c4: e8 27 00 00 00 callq 4006f0 <_ZN1AC1Ev>
4006c9: 48 8d 45 f0 lea -0x10(%rbp),%rax
4006cd: 48 89 c7 mov %rax,%rdi
4006d0: e8 3f 00 00 00 callq 400714 <_ZN1AD1Ev>
4006d5: b8 00 00 00 00 mov [=11=]x0,%eax
4006da: 48 8b 55 f8 mov -0x8(%rbp),%rdx
4006de: 64 48 33 14 25 28 00 xor %fs:0x28,%rdx
4006e5: 00 00
4006e7: 74 05 je 4006ee <main+0x48>
4006e9: e8 92 fe ff ff callq 400580 <__stack_chk_fail@plt>
4006ee: c9 leaveq
4006ef: c3 retq
请注意,根据底层架构和编译器,您的输出可能与我的不同,但结构通常应该相同。
您可以看到编译器自动生成对构造函数 callq 400714 <_ZN1AD1Ev>
和析构函数 callq 400714 <_ZN1AD1Ev>
的调用。构造函数的汇编代码是:
00000000004006f0 <_ZN1AC1Ev>:
4006f0: 55 push %rbp
4006f1: 48 89 e5 mov %rsp,%rbp
4006f4: 48 83 ec 10 sub [=12=]x10,%rsp
4006f8: 48 89 7d f8 mov %rdi,-0x8(%rbp)
4006fc: bf 04 00 00 00 mov [=12=]x4,%edi
400701: e8 8a fe ff ff callq 400590 <_Znwm@plt>
400706: 48 89 c2 mov %rax,%rdx
400709: 48 8b 45 f8 mov -0x8(%rbp),%rax
40070d: 48 89 10 mov %rdx,(%rax)
400710: 90 nop
400711: c9 leaveq
400712: c3 retq
400713: 90 nop
析构函数的程序集:
0000000000400714 <_ZN1AD1Ev>:
400714: 55 push %rbp
400715: 48 89 e5 mov %rsp,%rbp
400718: 48 83 ec 10 sub [=13=]x10,%rsp
40071c: 48 89 7d f8 mov %rdi,-0x8(%rbp)
400720: 48 8b 45 f8 mov -0x8(%rbp),%rax
400724: 48 8b 00 mov (%rax),%rax
400727: 48 89 c7 mov %rax,%rdi
40072a: e8 31 fe ff ff callq 400560 <_ZdlPv@plt>
40072f: 90 nop
400730: c9 leaveq
400731: c3 retq
400732: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
400739: 00 00 00
40073c: 0f 1f 40 00 nopl 0x0(%rax)