天天看點

c++預設構造函數的一個問題

csdn上看到一個問題 http://topic.csdn.net/u/20090714/00/e7dad941-daf0-4905-a679-7a56ff412f77.html?80540#replyachor

原文如下:

#include <iostream>

using namespace std;

class test{

public:

//test(){}

int x;

int y;

};

int main()

{

test t;

cout < <t.x < <t.y < <endl;

return 0;

}

代碼如上,按理說我在test中沒有定義構造函數,編譯器會為我添加一個預設構造函數,将x和y初始化為随機值,但是實際上當我運作上面的程式的時候,ERROR,提示我t沒有初始化。

經過我的測試,

c++預設構造函數的一個問題
c++預設構造函數的一個問題

 其中watergear 的回複,我覺得很好:

你估計用的是debug模式,你改為release模式,估計就沒有錯誤警告了。

在debug模式下,VC會為一些未初始化的記憶體空間,填充一些固定值(例如0xCC)。好處是,當調試程式時,如果把異常選項打開,可以很容易發現記憶體越界或洩漏的情況。

而release模式,則會忽略所有這些錯誤。

讨論有沒有預設構造函數,是沒有意義的。因為即使編譯自動生成構造函數,那也是什麼都沒做的空函數。有和沒有是一樣的。

我們看反彙編

004113DD    A1 A0824100     mov     eax, dword ptr [<&MSVCP80D.std::endl>]

004113E2    50              push    eax

004113E3    8BFC            mov     edi, esp

004113E5    8B4D F8         mov     ecx, dword ptr [ebp-8]

004113E8    51              push    ecx

004113E9    8BDC            mov     ebx, esp

004113EB    8B55 F4         mov     edx, dword ptr [ebp-C]

004113EE    52              push    edx

004113EF    8B0D 9C824100   mov     ecx, dword ptr [<&MSVCP80D.std::cout>]         ; MSVCP80D.std::cout

004113F5    FF15 98824100   call    dword ptr [<&MSVCP80D.std::basic_ostream<char,>; MSVCP80D.std::basic_ostream<char,std::char_traits<char> >::operator<<

004113E5    8B4D F8         mov     ecx, dword ptr [ebp-8]      //t.y

004113EB  mov         edx,dword ptr [t]

004113EB    8B55 F4         mov     edx, dword ptr [ebp-C]    //t.x

為什麼t.x 不是ebp-4 呢

004113DD  mov         eax,dword ptr [__imp_std::endl (4182A0h)]

004113E2  push        eax 

位置讓給endl 了

從這裡可以看出,class 配置設定在堆棧裡了,如果用new 呢

test* t=new test();

我們看到t->x,t->y 都初始化為0

總結:

          配置設定記憶體的方式不同

test t; 這是在堆棧中配置設定的,沒有預設的構造函數

test t=new test(); 堆配置設定,有預設的構造函數,t->x,t->y 初始化為0

 如果test t有顯示構造函數

test()

{

         x=1;

         y=2;

}

那麼test t;  會調用構造函數