2009年11月15日 星期日

C++ Const

作個小實驗。

void func_a(const int& a) {
  int& b = const_cast<int&>(a);
  b = 200;
  cout << a << ", " << &a << endl;
}

int main() {
  const int a = 100;
  cout << a << ", " << &a << endl;
  func_a(a);
  cout << a << ", " << &a << endl;
}

-------------------------------------------------
100, 0012FED4
200, 0012FED4
100, 0012FED4
-------------------------------------------------

可以看到,在func_a內,明明a的值已經被改成200了(可以由變數位址確認)。為了確認這一點,加上了第四個cout,如下。

cout << *(int*)&a << ", " << &a << endl;

-------------------------------------------------
100, 0012FED4
200, 0012FED4
100, 0012FED4
200, 0012FED4
-------------------------------------------------

可以看到第四個cout果然印出a的內容已改變為200。但是第三個cout卻是印出原來的值100,這是為什麼?答案在將程式反組譯,從組合語言的層面來看就很明顯了。

cout << a << ", " << &a << endl;
0041E6B2 push offset std::endl (41C528h)
0041E6B7 lea eax,[a]
0041E6BA push eax
0041E6BB push offset string ", " (4570C8h)
0041E6C0 push 64h
0041E6C2 mov ecx,offset std::cout (460888h)
0041E6C7 call std::basic_ostream<char,std::char_traits<char> >::operator<< (41C663h)
0041E6CC push eax
0041E6CD call std::operator<<<std::char_traits<char> > (41CB8Bh)
0041E6D2 add esp,8
0041E6D5 mov ecx,eax
0041E6D7 call std::basic_ostream
0041E6DC mov ecx,eax
0041E6DE call std::basic_ostream<char,std::char_traits<char> >::operator<< (41CBB8h)

注意紅色那行指令。編譯器直接把100(64h)這個常數值push進堆疊,而不再從常數變數a裡取出值來。這就是為什麼在func_a內,a的值已被改變,最後卻還印出原來的值的原因。

2009年11月10日 星期二

背景重覆模式

新增了一個類似CSS的background repeat功能,可以在關卡裡指定貼圖背景及地圖背景水平及垂直方向的重覆模式。有了這個功能之後,背景就可以使用簡單的磚塊圖片重覆鋪滿,或者也能很容易的實作出多重背景捲動。底下的抓圖是使用repeat-x功能作出多重背景捲動。


總共使用了三張底圖,全景底圖、白雲及太陽寶寶,全部設定成水平重覆貼圖。程式執行後,三張圖各以不同的速度去改變自己的水平座標,結果就在畫面上呈現出三層的背景捲動。

2009年11月7日 星期六

Script Editor

結果又把Script Editor的Syntax Color功能拿掉了,因為我把Editor本身用到的Rich Edit換回一般的Edit,所以也就沒辨法支援顏色。原因是加入了完整的Edit Hotkey支援,例如Ctrl+C/Ctrl+X等等。為了省麻煩,減少複雜度所以才換回一般的Edit元件。

除此之外直接在Script Edit內作的改變終於也能夠存檔了。因為原本存檔的定義是針對專案,現在再加上也可對程式原始碼檔作存檔,所以在操作的定義上需要再多作一點判定,同時在專案切換或程式關閉時也需要多加對變動檔案需存檔的提醒。

目前還缺Find/Replace及GotoLine的功能需要補充。

Related Posts Plugin for WordPress, Blogger...