[英]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.