• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            被無視的伊謝爾倫

            雕欄玉砌應猶在,只是朱顏改

              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
              9 隨筆 :: 0 文章 :: 6 評論 :: 0 Trackbacks

            2008年7月21日 #

            轉眼已經2008年了,留下一筆,繼續努力!!
            posted @ 2008-07-21 20:51 愛上青菜的包子 閱讀(146) | 評論 (0)編輯 收藏

            2006年11月29日 #

            首先需要確認的是,編譯器對非虛方法使用靜態聯編,對虛方法使用動態聯編。
            看起來,在大多數情況下,動態聯編都更好,因為它讓程序能夠選擇為特定類型設計的方法,這樣問題就來了,既然動態聯編這么好,為什么還要設計兩種類型的聯編?為什么默認的聯編方法是靜態的而不是動態?

            原因關鍵就在于效率。Strousstrup說過(很經典,呵呵):C++的指導原則之一是,不要為不使用的特性付出代價(內存或處理時間)。

            因為通常情況下,編譯器處理虛函數的方法為:給每個對象添加一個隱藏成員,該成員中保存了一個指向函數地址數組的指針(稱為虛函數表 virtual function table,vtbl)。虛函數表中存儲了為類對象進行聲明的虛函數的地址。例如,基類包含一個指針,指向了基類中所有虛函數的地址表,派生類對象將包含一個指向獨立地址表的指針,如果派生類提供了虛函數的新定義,該虛函數表將保存新函數的地址,如果沒有重新定義,則保留原始版本的地址。調用虛函數時,程序將查看存儲在對象中的vtbl地址,然后轉向相應的函數地址表。

            所以顯而易見的是,使用虛函數時,在內存和執行速度方面有一定的額外成本,包括:
            每個對象都將增大,增大量為存儲地址的空間;對每個類,編譯器都創建一個虛函數地址表(數組);每個函數調用都需要執行一步額外的操作,即到表中查找地址。

            所以咱們要養成的習慣是,在設計類時,可能包含一些不在派生類重新定義的成員函數,那么這些函數就不要設置為虛函數。這樣首先會有更好的效率,其次被聲明為虛函數的成員函數就表明是預期在派生類中會被重新定義的,在閱讀代碼時也將比較方便。
            posted @ 2006-11-29 17:27 愛上青菜的包子 閱讀(610) | 評論 (0)編輯 收藏

            2006年11月10日 #

            最近全面檢查了下身體,拿到體檢報告的時候,發現有一項血液尿酸偏高,醫生在后面批注,少食動物內臟。

            疑惑了一下,正準備網上查查,結果有同事發了封公司郵件,正好是說這個事的,貌似出現該情況的人也有不少。看了看內容,如下:

            出現尿酸偏高的現象,這是酸性體質的表現。是由于進食過多高蛋白、高脂肪、高糖類美食造成的。要改變偏酸性體質,關鍵在于飲食,要多吃堿性食物。所謂食物的酸堿性,是說食物中的無機鹽屬于酸性還是屬于堿性。一般金屬元素鈉、鈣、鎂等,在人體內其氧化物呈堿性,含這種元素較多的食物就是堿性食物,如大豆、豆腐、菠菜、萵筍、蘿卜、土豆、藕、洋蔥、海帶、西瓜、香蕉、梨、蘋果、牛奶等。一些食物中含有較多的非金屬元素,如磷、硫、氯等,在人體內氧化后,生成帶有陰離子的酸根,屬于酸性食物。如豬肉、牛肉、雞肉、鴨、蛋類、鯉魚、牡蠣、蝦,以及面粉、大米、花生、大麥、啤酒等。所以不要誤以為蘋果等吃起來很酸就是酸性食物,那是大錯特錯的,剛好相反,蘋果是一種堿性的食物。

            酸性體質,健康新殺手

            ???吃得好了,身體卻變?"酸"了
            ???"俺們那年代,缺飯又少菜;如今這年代,吃得真不賴"的確如此,現代人生活水平不斷在提高,每天大魚大肉,頓頓都離不開葷,年輕人去麥當勞、肯德基吃洋快餐更是家常便飯.可是根據一項調查研究表明:生活水平越來越好,醫療水平越來越高,現代文明病卻越來越多;發病率越來越高;患者越來越年輕化。有數字顯示:我國目前的高血壓人群已達到1.6?個億,我國的高血脂人群是?6500萬,糖尿病人?4800萬并以每年10%的速度高速增長,每年死于癌癥的有130?多萬人,死于心腦血管疾病的有200?多萬人。70年代我們國家就呼吁要讓高血壓低頭,可現在我們在高血壓面前低了頭。我國心臟病的發病年齡比80?年代初期整整提早了15年,也就是說原來50歲開始得心臟病的,現在35歲的人就開始得心臟病。多么觸目驚心的數字,而這些數字只是官方統計,還沒有加上未檢查出來的。我們不禁要問:這到底是怎么了?越來越多的醫學家、營養學家和研究機構為此現象設立課題進行研究,最后得出一致結論:酸性體質是病魔元兇。
            ????挖出酸性體質的根
            ????那么酸性體質是怎么來的呢?現代醫學研究向我們揭示了真相:魚肉禽蛋油米面等這些高蛋白、高脂肪、高糖類美食在為我們提供能量和營養的同時,也在提供大量的酸性物質。那么到底什么物質產生什么酸呢??我們一起來看看:?蛋白質(主要來源于瘦肉、魚、蛋等)在體內代謝產生含硫氨基酸、含磷氨基酸、尿酸等等;脂肪(主要來源于肥肉、油等)在體內代謝產生烴丁酸、乙酰乙酸(也稱酮酸);碳水化合物(糖類,主要來源于米面)在體內代謝產生甘油酸、丙酮酸、乳酸。
            ????"酸"不除,后患無窮
            ????人體攝入的酸性食物過多,超過了人體酸堿平衡的調節能力,肝腎等身體重要部位超負荷運作,人體的酸堿平衡就會被破壞,使體內酸堿失衡,甚至出現輕度酸中毒反應,這就是我們所說的酸性體質。
            ????其實我們人體就象個養魚的池塘,占人體體重70%的體液就是池塘里的水,水被污染了魚就要生病死亡,同樣的道理,人體體液被酸性物質污染了,組成我們人體的60萬億個細胞的生態環境就會發生變化,細胞就會發生突變和病變而影響我們的健康。我們都知道:酸性物質沉積在肝臟中會產生脂肪肝;酸性物質沉積在腎臟中會影響腎的排泄功能,使尿酸偏高而產生痛風;酸性物質沉積在關節或組織器宮內引起相應炎癥,導致關節炎等疾病;酸性物質沉積在胰腺中,會影響胰島細胞的活性、影響胰島素的敏感性引發糖尿病及其并發癥等等。更為嚴重的是酸性物質沉積在血液里、血管壁使血管壁增厚,引起動脈硬化,引發中風、心肌梗塞等各種心腦血管疾病。

            …………

            含鈉、鉀、鈣、鎂等金屬元素較多的乃是堿性食品。并非味道酸的就是酸味食品,應該掌握一點:所有酸味的水果、豆制品都為堿性食物而不是酸性食物,堿性食物被認為是具有美容作用的食物。
            豆腐、牛奶、芹菜、土豆、竹筍、香菇、胡蘿卜、海帶、綠豆、香蕉、西瓜、草莓等及大部分的蔬菜、水果都是堿性的。
            食物的“酸堿性”會影響體態和皮膚健美。
             經測定,弱堿性的食物有:豆腐、豌豆、大豆、綠豆、油菜、芹菜、番薯、蓮藕、洋蔥、茄子、南瓜、黃瓜、蘑菇、蘿卜、牛奶等。而呈堿性的食物有:菠菜、白菜、卷心菜、生菜、胡蘿卜、竹筍、馬鈴薯、海帶、柑橘類、西瓜、葡萄、香蕉、草莓、板粟、柿子、咖啡、葡萄酒等。  還有一些食物因吃起來酸,人們就錯誤地把它們當成了酸性食物,如山植、西紅柿、醋等,其實這些東西正是典型的堿性食物

            多吃堿性食物。研究發現,多食堿性食物,可保持血液呈弱堿性,使得血液中乳酸、尿素等酸性物質減少,并能防止其在管壁上沉積,因而有軟化血管的作用,故有人稱堿性食物為“血液和血管的清潔劑”。這里所說的酸堿性,不是食物本身的性質,而是指食物經過消化吸收后,留在體內元素的性質。常見的酸性元素有氮、碳、硫等;常見的堿性元素有鉀、鈉、鈣、鎂等。有的食物口味很酸,如番茄、橘子,卻都是地地道道的強堿性食物,因為它們在體內代謝后的最終元素是鉀元素等。

            何謂酸性或堿性食物  所謂酸性食物或堿性食物,并不是指味道酸或咸的食物,而是指食物經過消化吸收和代謝后產生的陽離子或陰離子占優勢的食物。也就是說,某種食物如經代謝后產生的鉀、鈉、鈣、鎂等陽離子占優勢的則屬堿性食物;而代謝后產生磷、氯、硫等陰離子占優勢的食物屬酸性食物。檸檬、柑桔、楊桃等味道雖酸,但它經代謝后,有機酸變成了水和二氧化碳,后者經肺呼出體外,剩下的陽離子占優勢,仍屬堿性食物;同理,肉、魚、蛋類和米面雖無酸味,但代謝后產生的陰離子較多,仍屬于酸性食物。因此,不能從食物的味道來區分酸性或堿性食物

            看起來挺恐怖的。。。看來得注意下伙食了,以后要多吃水果、蔬菜。。。~~~

            posted @ 2006-11-10 16:09 愛上青菜的包子 閱讀(234) | 評論 (0)編輯 收藏

            2006年10月26日 #

            這幾天拿到公司以前項目中的一個用C++Builder做的程序,在我機器上調試,結果提示出錯:Operation not applicable

            使用斷點跟蹤之后發現錯誤出在使用TQuery時執行open方法時,回追根源,得出以下反饋:

            m_pqQuery -> SQL -> Add(? " Select?*?From?Table1?Where?Id?=?:PId? " ?);
            m_pqQuery
            -> ParamByName(? " PId " ?) -> AsInteger????? = ?某個int變量;


            執行完這句之后,按正常情況,參數PId應該被賦予了一個整形值,但是Debug跟蹤顯示其值還是跟未賦值前是同樣表示的未知值。所以在執行open方法時出錯了。

            如果我不是用該方法,直接把SQL語句寫死:

            m_pqQuery -> SQL -> Add(? " Select?*?From?Table1?Where?Id?=?0? " ?);


            運行正常

            或者用

            char ?sql[ 80 ];
            int ?n? = ?某整形變量?;
            sprintf(sql,
            " Select?*?From?Table1?Where?Id?=?%d " ,n);
            pqQuery
            -> SQL -> Add(sql);


            也運行正常

            查了下,原來給參數賦值的方法并沒有錯誤,編譯也能通過,況且以前該程序肯定是能正常運行的。。真是奇怪為什么在我這里就賦不上值。。調試了很久也沒能找到原因,只好作罷,為了順利運行,只能改為sprintf和直接連接字符串的方式。
            在這里記上一筆,希望以后能夠找到原因。。。

            posted @ 2006-10-26 21:25 愛上青菜的包子 閱讀(369) | 評論 (0)編輯 收藏

            2006年9月28日 #

            1. 重載<<操作符
              要重新定義<<操作符,以便將它和cout一起用來顯示對象的內容,請定義下面的友元操作符函數:
              ostream?&?operator?<<?(ostream?&?os,const?c_name?&?obj)
              {
              os?
              <<?;//?display?object?contents
              return?os;
              }

              其中c_name是類名。如果該類提供了能夠返回所需內容的公有方法,則可在操作符函數中使用這些方法,這樣便不會將他們設置為友元函數了。
            2. 轉換函數
              要將單個值轉換為類類型,需要創建原型如下所示的類構造函數:
              c_name(type_name?value);

              其中c_name為類名,type_name是要轉換的類型的名稱。
              要將類轉換為其他類型,需要創建原型如下所示的類成員函數:
              operator?type_name();

              雖然該函數沒有聲明返回類型,但應返回所需類型的值。
              使用轉換函數時要小心。可以在聲明構造函數時使用關鍵字explicit,以防止它被用于隱式轉換。
            3. 其構造函數使用new的類
              如果類使用new操作符來分配類成員指向的內存,在設計時應采取一些預防措施。
            • 對于指向的內存是由new分配的所有類成員,都應在類的析構函數中對其使用delete,該操作符將釋放分配的內存。
            • 如果析構函數通過對指針類成員使用delete來釋放內存,則每個構造函數都應當使用new來初始化指針,或將它設置為空指針。
            • 構造函數中要么使用new[],要么使用new,而不能混用。如果構造函數使用的是new[],則析構函數應使用delete[];如果構造函數使用的是new,則析構函數應適用delete。
            • 應定義一個分配內存(而不是將指針指向已有內存)的復制構造函數。這樣程序能夠將類對象初始化為另一個對象。這種構造函數原型如下:
              className(const?className?&)
            • 應定義一個重載賦值操作符的類成員函數,其函數定義如下(其中c_pointer是c_name的類成員,類型為指向type_name的指針)。下面的范例假設使用new[]來初始化變量c_pointer):
              c_name?&?c_name::operator?=?(const?c_name?&?cn)
              {
              if?(this?==?&?cn)
              return?*this;

              delete?[]?c_pointer;
              //?set?size?number?of?type_name?units?to?be?copyied
              c_pointer?=?new?type_name[size];
              //?then?copy?data?pointed?to?by?cn.c_pointer?to
              //?location?pointed?to?by?c_pointer

              return?*this;
              }

            本文對我前面幾篇隨筆中提到的問題也作出了一個總結,感覺很有必要記下來。
            以上內容原文引用自參考書籍中內容。

            參考書籍:C++PrimerPlus author:Stephen Prata

            posted @ 2006-09-28 15:18 愛上青菜的包子 閱讀(793) | 評論 (1)編輯 收藏

            ?

            const ? int ?BUF? = ? 512 ?;

            class ?JustTesting
            {
            ????
            private :
            ????????JustTesting(
            const ? string ? & ?s? = ? " Just?Testing " , int ?n? = ? 0 )
            ????????
            {} ?
            ????????
            ~ JustTesting() {}
            ????
            public :
            ????
            }
            ;

            int ?main()
            {
            ????
            char ? * ?buffer? = ? new ? char ?[BUF];

            ????JustTesting?
            * pc1, * pc2, * pc3, * pc4;

            ????pc1?
            = ? new ?(buffer)?JustTesting;
            ????pc2?
            = ? new ?JustTesting(? " ?Heap1? " ?,? 20 ?);

            ????pc3?
            = ? new ?(buffer? + ? sizeof ?(JustTesting))?JustTesting( " Bad?Idea " , 6 );?? // ?此處用一個JustTesging對象大小的偏移量避免pc3與pc1占用同一塊內存,因為如果類動態的為其成員分配內存,占用同一內存將會產生問題。?
            ????pc4? = ? new ?JustTesting( " Heap2 " , 10 )?

            ????

            ????delete?pc2;
            ????delete?pc4;
            ????delete?[]?buffer;
            ????
            return ? 0 ;
            }


            以上代碼片斷中,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操作符創建的對象調用析構函數。正常情況下將自動調用析構函數,這是需要顯示調用析構函數的少數幾種情況之一。
            顯式調用析構函數時,必須指定要銷毀的對象。由于有指向對象的指針,因此可以這樣寫:

            pc3->~JustTesting();
            pc1->~JustTesting();

            把這段代碼放到delete [] buffer;之前,這段程序才算完整無錯。

            參考書籍:C++PrimerPlus author:Stephen Prata

            posted @ 2006-09-28 14:42 愛上青菜的包子 閱讀(2320) | 評論 (3)編輯 收藏

            在使用new來初始化對象的指針成員時必須特別小心,以下是幾點注意事項:

            • 如果在構造函數中使用new來初始化指針成員,則應在析構函數中使用delete。
            • new和delete必須相互兼容。new對應于delete,new[]對應于delete[]。
            • 如果有多個構造函數,則必須以相同的方式使用new,要么都帶中括號,要么都不帶。因為只有一個析構函數,因此所有的構造函數都必須與它兼容。不過可以在一個構造函數中使用new來初始化指針,而在另外一個構造函數中將指針初始化為空(Null或0),這是因為delete(無論是帶中括號還是不帶中括號)可以用于空指針。
            posted @ 2006-09-28 14:41 愛上青菜的包子 閱讀(1893) | 評論 (1)編輯 收藏

            例如有以下class:

            class ?StringBad
            {
            ????
            private :
            ????????
            char ? * ?str;
            ????????
            int ?len;
            ?????????
            ????
            public :
            ????????StringBad(
            const ? char ? * ?s);
            ????????StringBad();
            ????????
            ~ StringBad();
            ????????
            }
            ;

            在構造函數和析構函數定義當中有如下定義:

            StringBad::StringBad( const ? char ? * ?s)
            {
            ????len?
            = ?std::strlen(s);
            ????str?
            = ? new ? char ?[len? + ? 1 ];
            ????
            }
            ?

            StringBad::StringBad()
            {
            ????len?
            = ? 4 ?;
            ????str?
            = ? new ? char [ 4 ];
            ????
            }
            ?

            StringBad::
            ~ StringBad()
            {
            ????
            ????delete?[]?str;
            }

            那么在程序當中如果有以下代碼:

            StringBad?sports( " Spinach?Leaves?Bow1?for?bollars " );
            StringBad?sailor?
            = ?sports;

            以上的第二條初始化語句將會調用什么構造函數?記住,這種形式的初始化等效于下面的語句:

            StringBad?sailor? = ?StringBad(sports);

            因為sports的類型為StringBad,因此相應的構造函數原型應該如下:

            StringBad( const ?StringBad? & );

            當我們使用一個對象來初始化另一個對象時,編譯器將自動生成上述構造函數(稱為復制構造函數,因為它創建對象的一個副本)。
            現在我們不妨總結一下所謂的隱式成員函數,即C++自動提供了以下這些成員函數:

            • 默認構造函數,如果沒有定義構造函數。
            • 復制構造函數,如果沒有定義。
            • 賦值操作符,如果沒有定義。
            • 默認析構函數,如果沒有定義。
            • 地址操作符,如果沒有定義。

            現在我們來看看我們沒有定義復制構造函數的情況下調用隱式復制構造函數將會出現什么情況。
            從構造函數定義的代碼片斷可以看到,當中使用new操作符初始化了一個指針str,而隱式的復制構造函數是按值進行復制的,那么對于指針str,將會進行如下復制:

            sailor.str? = ?sports.str;

            這里復制的不是字符串,而是一個指向字符串的指針!也就是說,我們將得到兩個指向同一個字符串的指針!由此會產生的問題將不言而喻。當其中一個對象調用了析構函數之后,其str指向的內存將被釋放,這個時候我們如果調用另一個對象,其str指向的地址數據會是什么?很明顯將會出現不可預料的結果。

            所以由此可見,如果類中包含了使用new初始化的指針成員,應當定義一個復制構造函數,以復制指向的數據,而不是指針,這被稱為深度復制。因為默認的淺復制(或成為成員復制)僅淺淺的賦值指針信息。

            我們再看以下代碼片斷,我們稍做修改:

            StringBad?headline1( " Celery?Stalks?at?Midnight " );
            StringBad?knot;
            knot?
            = ?headline1;

            這里的最后一行將與以上例子有所區別,現在是將已有對象賦給另一個已有對象,這將會采取其他操作,即使用重載的賦值操作符。(我們需要知道的是:初始化總是會調用復制構造函數,而使用=操作符時也可能調用賦值操作符)因為C++允許對象賦值,這是通過自動為類重載賦值操作符實現的。其原型如下:

            Class_name? & ?Class_name:: operator ? = ?( const ?Class_name? & );

            它接受并返回一個指向類對象的引用。
            與隱式的復制構造函數一樣,隱式的對象賦值操作符也會產生同樣的問題,即包含了使用new初始化的指針成員時,只會采用淺復制。所以我們需要使用同樣的解決辦法,即定義一個重載的賦值操作符來實現深度復制。

            所以綜上所述,如果類中包含了使用new初始化的指針成員,我們應該顯式定義一個復制構造函數和一個重載的賦值操作符來實現其深度復制,避免由此帶來的成員復制問題

            參考書籍:C++PrimerPlus author:Stephen Prata

            posted @ 2006-09-28 14:33 愛上青菜的包子 閱讀(1576) | 評論 (0)編輯 收藏

            很喜歡C++,學習也有一段時間了。但是看書+練手的同時,總感覺有必要將自己學習中覺得重要的地方整理出來,以便以后回頭參考。最終選擇了cppblog,呵呵。以后就在這里安家了~~
            筆記中參考了一些書籍中的范例和一些說明。都是自己學習過程中整理出來的,主要目的是給自己日后參考。
            posted @ 2006-09-28 14:23 愛上青菜的包子 閱讀(435) | 評論 (1)編輯 收藏

            僅列出標題  
            成人午夜精品无码区久久| 99久久国产主播综合精品 | 国产99久久久国产精品小说| 久久久久国产精品熟女影院| 欧美激情精品久久久久久| 久久久噜噜噜久久熟女AA片| 久久精品国产影库免费看| 亚洲香蕉网久久综合影视| 99久久免费国产精精品| 无码精品久久久久久人妻中字| 久久伊人色| AV无码久久久久不卡网站下载| 偷偷做久久久久网站| 国产一区二区精品久久| 日韩欧美亚洲国产精品字幕久久久| 久久精品国产精品青草app| 久久亚洲电影| 国产亚洲婷婷香蕉久久精品| 欧美亚洲国产精品久久| 国产精品激情综合久久| 久久精品一区二区影院| 无码人妻少妇久久中文字幕 | 久久久久久精品久久久久| 久久天天躁狠狠躁夜夜不卡| 人妻精品久久久久中文字幕69| 7777久久久国产精品消防器材| 精品久久久久久久| 久久精品蜜芽亚洲国产AV| 国产A三级久久精品| 亚洲精品NV久久久久久久久久 | 日本精品久久久久中文字幕| 久久人人爽人人爽人人AV东京热 | 久久99国产综合精品女同| 亚洲午夜精品久久久久久浪潮| 精品久久久久国产免费 | 亚洲欧美成人久久综合中文网 | 成人综合久久精品色婷婷| 成人国内精品久久久久影院VR| aaa级精品久久久国产片| 国产精品国色综合久久| 久久国产精品久久国产精品|