雕欄玉砌應猶在,只是朱顏改
2008年7月21日 #
2006年11月29日 #
2006年11月10日 #
多吃堿性食物。研究發現,多食堿性食物,可保持血液呈弱堿性,使得血液中乳酸、尿素等酸性物質減少,并能防止其在管壁上沉積,因而有軟化血管的作用,故有人稱堿性食物為“血液和血管的清潔劑”。這里所說的酸堿性,不是食物本身的性質,而是指食物經過消化吸收后,留在體內元素的性質。常見的酸性元素有氮、碳、硫等;常見的堿性元素有鉀、鈉、鈣、鎂等。有的食物口味很酸,如番茄、橘子,卻都是地地道道的強堿性食物,因為它們在體內代謝后的最終元素是鉀元素等。
何謂酸性或堿性食物 所謂酸性食物或堿性食物,并不是指味道酸或咸的食物,而是指食物經過消化吸收和代謝后產生的陽離子或陰離子占優勢的食物。也就是說,某種食物如經代謝后產生的鉀、鈉、鈣、鎂等陽離子占優勢的則屬堿性食物;而代謝后產生磷、氯、硫等陰離子占優勢的食物屬酸性食物。檸檬、柑桔、楊桃等味道雖酸,但它經代謝后,有機酸變成了水和二氧化碳,后者經肺呼出體外,剩下的陽離子占優勢,仍屬堿性食物;同理,肉、魚、蛋類和米面雖無酸味,但代謝后產生的陰離子較多,仍屬于酸性食物。因此,不能從食物的味道來區分酸性或堿性食物。看起來挺恐怖的。。。看來得注意下伙食了,以后要多吃水果、蔬菜。。。~~~
2006年10月26日 #
這幾天拿到公司以前項目中的一個用C++Builder做的程序,在我機器上調試,結果提示出錯:Operation not applicable
使用斷點跟蹤之后發現錯誤出在使用TQuery時執行open方法時,回追根源,得出以下反饋:
執行完這句之后,按正常情況,參數PId應該被賦予了一個整形值,但是Debug跟蹤顯示其值還是跟未賦值前是同樣表示的未知值。所以在執行open方法時出錯了。
如果我不是用該方法,直接把SQL語句寫死:
運行正常
或者用
也運行正常
查了下,原來給參數賦值的方法并沒有錯誤,編譯也能通過,況且以前該程序肯定是能正常運行的。。真是奇怪為什么在我這里就賦不上值。。調試了很久也沒能找到原因,只好作罷,為了順利運行,只能改為sprintf和直接連接字符串的方式。在這里記上一筆,希望以后能夠找到原因。。。
2006年9月28日 #
本文對我前面幾篇隨筆中提到的問題也作出了一個總結,感覺很有必要記下來。以上內容原文引用自參考書籍中內容。參考書籍:C++PrimerPlus author:Stephen Prata
?
以上代碼片斷中,pc1和pc3為布局new操作符來分配內存,而pc2和pc4為常規new操作符來分配內存?。對于常規new操作符分配的內存,可以直接使用:delete?pc2; 這樣的語句操作來釋放內存。而對于布局new操作符分配的內存就不能這樣做:delete?pc1;
因為pc1和pc3并沒有直接收到new操作符返回的地址,而是由布局操作符指向了buffer的地址,new/delete系統知道已分配的512字節塊buffer,但對布局new操作符對該內存塊做了何種處理一無所知。另一方面,buffer的地址是用new []初始化的,因此必須使用delete[]而不是delete。注意:即使buffer是使用new而不是new[]初始化的,delete pc1 也將釋放buffer,而不是pc1。
以上的代碼確實釋放了buffer:delete [] buffer;但是由此產生了新的問題,它沒有為布局new操作符在該內存塊中創建的對象調用析構函數,我們只需要在析構函數中放入一段顯示語句就可以清楚的看到,程序并沒有銷毀“JustTesting”和“Bad Idea”,也就是pc1和pc3指向的對象。那么這里就需要我們顯式的為布局new操作符創建的對象調用析構函數。正常情況下將自動調用析構函數,這是需要顯示調用析構函數的少數幾種情況之一。顯式調用析構函數時,必須指定要銷毀的對象。由于有指向對象的指針,因此可以這樣寫:
把這段代碼放到delete [] buffer;之前,這段程序才算完整無錯。
參考書籍:C++PrimerPlus author:Stephen Prata
在使用new來初始化對象的指針成員時必須特別小心,以下是幾點注意事項:
例如有以下class:
在構造函數和析構函數定義當中有如下定義:
那么在程序當中如果有以下代碼:
以上的第二條初始化語句將會調用什么構造函數?記住,這種形式的初始化等效于下面的語句:
因為sports的類型為StringBad,因此相應的構造函數原型應該如下:
當我們使用一個對象來初始化另一個對象時,編譯器將自動生成上述構造函數(稱為復制構造函數,因為它創建對象的一個副本)。現在我們不妨總結一下所謂的隱式成員函數,即C++自動提供了以下這些成員函數:
現在我們來看看我們沒有定義復制構造函數的情況下調用隱式復制構造函數將會出現什么情況。從構造函數定義的代碼片斷可以看到,當中使用new操作符初始化了一個指針str,而隱式的復制構造函數是按值進行復制的,那么對于指針str,將會進行如下復制:
這里復制的不是字符串,而是一個指向字符串的指針!也就是說,我們將得到兩個指向同一個字符串的指針!由此會產生的問題將不言而喻。當其中一個對象調用了析構函數之后,其str指向的內存將被釋放,這個時候我們如果調用另一個對象,其str指向的地址數據會是什么?很明顯將會出現不可預料的結果。
所以由此可見,如果類中包含了使用new初始化的指針成員,應當定義一個復制構造函數,以復制指向的數據,而不是指針,這被稱為深度復制。因為默認的淺復制(或成為成員復制)僅淺淺的賦值指針信息。
我們再看以下代碼片斷,我們稍做修改:
這里的最后一行將與以上例子有所區別,現在是將已有對象賦給另一個已有對象,這將會采取其他操作,即使用重載的賦值操作符。(我們需要知道的是:初始化總是會調用復制構造函數,而使用=操作符時也可能調用賦值操作符)因為C++允許對象賦值,這是通過自動為類重載賦值操作符實現的。其原型如下:
它接受并返回一個指向類對象的引用。與隱式的復制構造函數一樣,隱式的對象賦值操作符也會產生同樣的問題,即包含了使用new初始化的指針成員時,只會采用淺復制。所以我們需要使用同樣的解決辦法,即定義一個重載的賦值操作符來實現深度復制。
所以綜上所述,如果類中包含了使用new初始化的指針成員,我們應該顯式定義一個復制構造函數和一個重載的賦值操作符來實現其深度復制,避免由此帶來的成員復制問題參考書籍:C++PrimerPlus author:Stephen Prata
Powered by: C++博客 Copyright © 愛上青菜的包子