Destructor调用究竟是如何进行的

时间:2018-04-27 13:03:36

标签: constructor operating-system destructor

我想知道如何在c ++中调用构造函数或析构函数?我对操作系统的观点特别感兴趣。我也对我们运行用java编写的Android应用程序的情况感兴趣,我们想获得有关用户会话的信息。我们可以使用conatructor来设置会话开始的时间和destr来设置结束会话的时间并将数据保存在数据库中吗?实际操作系统是否处理析构函数调用或其他什么?提前谢谢!

1 个答案:

答案 0 :(得分:0)

我不熟悉Java如何处理构造函数和析构函数(Java涉及虚拟机层),但我会尝试从cpp的角度来回答这个问题。

您的问题的简短回答:操作系统不参与构造函数或析构函数(除非有堆分配,系统调用...)。编译器在生成机器代码时会在正确的位置插入对构造函数和析构函数的调用。

对于一个简单的程序如下:

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    $0x10,%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    $0x0,%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    $0x10,%rsp
  4006f8:       48 89 7d f8             mov    %rdi,-0x8(%rbp)
  4006fc:       bf 04 00 00 00          mov    $0x4,%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    $0x10,%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)