簡體   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