2

对于隐式定义的构造函数/析构函数,我们如何通过调试器检查值?

class base
{
 int a;
 public:
};

int main() 
{
 base b;
 return 0;
}

在这里,由于我没有提供任何构造函数/析构函数,它应该由编译器隐式提供(声明和定义)(根据书)。我如何使用调试器验证这一点。我试图设置一些断点,但不完全理解它是如何工作的。

4

4 回答 4

1

示例代码中的隐式构造函数必须做什么?根据 gdb,该函数base::base()未在我的 g++ 4.7.3 生成的目标代码中定义:

(gdb) b base::base()
Function "base::base()" not defined.

该构造函数的一个简单任务,例如需要调用它的派生类,编译器就必须合成它:

class base
{
 int a;
 public:
};

class derived : public base
{
public:
  derived() {};
};

int main(int argc, const char *argv[])
{
    derived d;
    return 0;
}

现在,base::base()可以调试该函数:

(gdb) b base::base() 
Breakpoint 1 at 0x400516: file test_impl_ctr.cpp, line 1.

当然,在构造函数的空实现中几乎没有什么可发现的(在这种情况下),但好奇心得到了满足 :)!

于 2013-06-15T15:38:55.233 回答
0

忘记构造函数 - 在编译程序后,甚至不能保证您的 base以任何有意义的形式存在。事实上,优化编译器可能会完全删除它,而只是为int base::a.

类、构造函数、析构函数、函数等是作为 C++ 编程概念存在的概念抽象,并由标准保证产生某些行为。编译程序并检查汇编指令后,您不一定会发现实际机器指令与 C++ 编程概念/抽象之间有任何对应关系。

因此,由于您隐式定义的构造函数实际上并没有做任何事情,编译器没有义务为它生成任何实际代码。从概念上讲,它仍然作为 C++ 概念存在,但不一定由任何实际的机器代码实现。

于 2013-06-15T15:19:24.633 回答
0

假设Visual Studio,您可以通过在您声明的行中放置一个断点来查看生成的汇编代码b,让它命中断点,然后按Alt+8。但是,除了调用每个成员的构造函数/析构函数之外,默认构造函数/析构函数不起作用,在您的情况下这将是空的。

于 2013-06-15T15:22:02.540 回答
0

根据 C++ 标准,C++ 编译器的行为就像它完成了你书中解释的所有事情一样。但是,如果这些东西没有可见的行为,例如发出一些输出,则可以随意跳过它们。

由于您示例中的程序不包含任何具有可见效果的代码,因此编译器可能会生成一个不执行任何操作的可执行文件。

于 2013-06-15T16:31:14.533 回答