根据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 文件来测试它。我假设没有人有时间和精力来阅读代码,但将其放在这里以防万一。
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 构造函数的主体会运行。