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沒有初始化。
經過我的測試,
其中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; 會調用構造函數