隐式编译器创建的默认构造函数是否可以有多个 null 主体?

问题描述 投票:0回答:1

根据IBM网站,答案是:不会。

我有这个项目有点难倒我:

这是声明一个名为 StackWalkerToConsole 的类的实例,没有定义默认构造函数的地方:

void func5()
{
  StackWalkerToConsole sw;
  ...
}

这会以某种方式导致其父类的用户定义构造函数之一被调用:

StackWalker::StackWalker(int options, LPCSTR szSymPath, DWORD dwProcessId, HANDLE hProcess)
{
  // The function has a body, I just removed it for clarity's sake.
  ...
}

所以我在这个构造函数上放置了一个断点,并使用调用堆栈查看了 StackWalkerToConsole 的默认构造函数。由于源码中没有定义,所以只能看它的反汇编:

StackWalker_VC2017.exe!StackWalkerToConsole::StackWalkerToConsole(void):
0000000140008210  mov         qword ptr [rsp+8],rcx  
0000000140008215  push        rdi  
0000000140008216  sub         rsp,40h  
000000014000821A  call        qword ptr [__imp_GetCurrentProcess (014012E060h)]  
0000000140008220  mov         qword ptr [rsp+30h],rax  
0000000140008225  call        qword ptr [__imp_GetCurrentProcessId (014012E068h)]  
000000014000822B  mov         rcx,qword ptr [rsp+30h]  
0000000140008230  mov         qword ptr [rsp+20h],rcx  
0000000140008235  mov         r9d,eax  
0000000140008238  xor         r8d,r8d  
000000014000823B  mov         edx,3Fh  
0000000140008240  mov         rcx,qword ptr [this]
  
0000000140008245  call        StackWalker::StackWalker (0140002F1Dh)  

000000014000824A  mov         rax,qword ptr [this]  
000000014000824F  lea         rcx,[StackWalkerToConsole::`vftable' (01400ED6C0h)]  
0000000140008256  mov         qword ptr [rax],rcx  
0000000140008259  mov         rax,qword ptr [this]  
000000014000825E  add         rsp,40h  
0000000140008262  pop         rdi 

这个编译器定义的构造函数正在调用 2 个 WinApi 函数:GetCurrentProcess 和 GetCurrentProcessId 并调用 StackWalker 的用户定义构造函数。

有谁知道这是为什么吗?我应该提一下,父类 StackWalker 也没有任何用户定义的默认构造函数。

如果需要更多信息,我很乐意提供。感谢您阅读本文。

编辑:这是代码的 github:这是一个很小的项目,只有 1 个 cpp 文件和 1 个 main.cpp 文件来测试它。我假设没有人有时间和精力来阅读代码,但将其放在这里以防万一。

在帖子中,我引用了 main.cpp 中的第 41 行和 StackWalker.cpp 中的第 929 行

c++ winapi constructor x86 default-constructor
1个回答
0
投票
您引用的课程:

class StackWalkerToConsole : public StackWalker { protected: virtual void OnOutput(LPCSTR szText) { printf("%s", szText); } };
有一个隐式声明的默认构造函数,看起来与此类似:

StackWalkerToConsole::StackWalkerToConsole() : StackWalker() {}
它调用 StackWalker 的 

this 构造函数

StackWalker(int options = OptionsAll, LPCSTR szSymPath = NULL, DWORD dwProcessId = GetCurrentProcessId(), HANDLE hProcess = GetCurrentProcess());

StackWalker

 
确实有一个用户定义的默认构造函数,就是这个可以用零参数调用)

因此,虽然

StackWalkerToConsole

 的默认构造函数没有主体,但它的基类是使用默认参数 
StackWalker(OptionsAll, NULL, GetCurrentProcessId(), GetCurrentProcess())
 进行初始化的,并且 StackWalker 构造函数的主体会运行。

© www.soinside.com 2019 - 2024. All rights reserved.