繁体   English   中英

C ++构造函数是否有堆栈框架

[英]C++ Is there a stack frame for the constructor

在C ++中,当调用函数时,会向调用堆栈添加一个新的堆栈帧,其中包含其参数和局部变量(以及其他内容)。 调用对象构造函数时是否也会发生这种情况? 如果是这样,当构造函数使用初始化列表时,这会改变吗? 这个堆栈框架的结构是什么? 它是否包含对象的成员变量(在执行构造函数后必须在堆中)?

您不需要特别考虑构造函数。 它只是一种功能 - 例如,这个C ++代码是

class Test
{
private:
    int m_a;
public:
    Test() : m_a(0) { puts("Test::Test()"); }
    explicit Test(int i) : m_a(i) { puts("Test::Test(int)"); }
    void f(char c) { puts("Test::f(char)"); }
    ~Test() { puts("Test::~Test()");
};

int main()
{
    Test t1;
    Test t2(3);

    t1.f('a');
}

几乎相似

struct Test
{
    int m_a;
};

void Test__ctor_0(Test *thiz) { thiz->m_a = 0; puts("Test::Test()"); }
void Test__ctor_1(Test *thiz, int i) { thiz->m_a = i; puts("Test::Test(int)"); }
void Test__f(Test *thiz, char c) { puts("Test::f(char)"); }
void Test__dtor_(Test *thiz) { puts("Test::~Test()"); }

int main()
{
    struct Test t1;
    Test__ctor_0(&t1);

    struct Test t2;
    Test__ctor_1(&t2, 3);

    Test__f(&t1, 'a');

    Test__dtor_(&t1);
    Test__dtor_(&t2);
}

这个C代码。

当然,可以在调用ctor时创建堆栈帧,如果它没有内联,或者编译器优化调用而不是创建堆栈帧以减少性能下降。

(在x86的cdecl中, this指针通过ecx寄存器发送,与其他参数不同。因此,如果构造函数不使用任何局部变量且没有任何其他参数,则可能无法创建堆栈帧。)

构造与任何其他方法调用一样处理。

如果优化器没有内联,则会创建一个堆栈帧,其中包含一个隐式的“this”指针和所有传入的参数。

大多数架构的ABI通过将this -pointer放入特定寄存器或通过将其推入特定位置的堆栈来调用成员函数。 构造函数在语言方面有点不寻常,但从ABI的角度来看,它们遵循这种模式。

通常, this -pointer被视为函数的隐式第一个参数。 例如,在正常的x86调用约定下,指向对象的指针位于堆栈的“底部”(按内存顺序)。 成员变量本身不在堆栈中; 这没有任何意义,因为构造函数(与其他成员函数一样)可能需要写入这些变量,而这些写入需要影响对象的“真实”副本。 因此,将指针推向它们。

对象构造不仅仅涉及构造函数体的执行。 首先,所有的基子对象和子对象构件被初始化, 然后才确实的构造器本体运行。 因此,当为对象构造选择特定构造函数时,子对象构造函数首先运行,并且它们的参数由原始构造函数的初始化列表给出。 之后,构造函数体或多或少像正常函数一样运行,其中参数从构造函数参数填充。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM