關(guān)于C++的坑有哪些

這篇文章主要講解了“關(guān)于C++的坑有哪些”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“關(guān)于C++的坑有哪些”吧!

創(chuàng)新互聯(lián)是一家專注于網(wǎng)站設(shè)計、網(wǎng)站制作與策劃設(shè)計,張家口網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)十多年,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:張家口等地區(qū)。張家口做網(wǎng)站價格咨詢:18982081108

1. string的字符串拼接,導(dǎo)致coredump

關(guān)于C++的坑有哪些

該問題的核心點在于第9行,竟然是可以編譯通過,其原因是x+"-",會被轉(zhuǎn)成char*,然后與to_string疊加導(dǎo)致BUG。

2. map的迭代器刪除

map要刪除一個元素,通常通過erase()函數(shù)來完成,但是要注意,如果我們傳入了一個iterator作為erase的參數(shù)來刪除當(dāng)前迭代器所指向的元素,刪除完成后iterator會失效,產(chǎn)生未定義行為。

正確的使用方法應(yīng)該是接收erase()的返回值,讓iterator指向被刪除元素的下一個元素或者end()。

for  ( auto  iter = m.begin(); iter != m.end(); iter++) {    if  (...)    iter = m.erase(iter);    }

但是上述代碼仍然有錯誤,因為如果觸發(fā)了刪除,那么iter再下一輪循環(huán)時會指向下下個元素,所以正確的寫法應(yīng)該是:

for  ( auto  iter = m.begin(); iter != m.end();) {    if  (...) {    iter = m.erase(iter);    continue ;    }  else  {    iter++;    }    }

3. stringstream的性能問題

  1. 鴻蒙官方戰(zhàn)略合作共建——HarmonyOS技術(shù)社區(qū)

  2.  stringstream的清空是clear之后,置空。

  3.  stringstream在任何情況下都比snprintf慢。

  4.  memset是個很慢的函數(shù),寧愿新創(chuàng)建對象。

  5.  上述測試結(jié)果是單線程,改成多線程,同樣成立。

  6.  str += “a”, 比 str =str+ “a” 效率高很多,后者會創(chuàng)建新對象。

4. 智能指針(shared_ptr)使用注意

4.1盡量使用make_shared初始化

提高性能

std::shared_ptr<Widget> spw(newWidget);

需要分配兩次內(nèi)存。每個std::shared_ptr都指向一個控制塊,控制塊包含被指向?qū)ο蟮囊糜嫈?shù)以及其他東西。這個控制塊的內(nèi)存是在std::shared_ptr的構(gòu)造函數(shù)中分配的。因此直接使用new,需要一塊內(nèi)存分配給Widget,還要一塊內(nèi)存分配給控制塊

autospw = std::make_shared<Widget>();

一次分配就足夠了。這是因為std::make_shared申請一個單獨的內(nèi)存塊來同時存放Widget對象和控制塊。這個優(yōu)化減少了程序的靜態(tài)大小,因為代碼只包含一次內(nèi)存分配的調(diào)用,并且這會加快代碼的執(zhí)行速度,因為內(nèi)存只分配了一次。另外,使用std::make_shared消除了一些控制塊需要記錄的信息,這樣潛在地減少了程序的總內(nèi)存占用。

異常安全

processWidget(std::shared_ptr<Widget>( new  Widget),   //潛在的資源泄露     computePriority());

上述代碼存在內(nèi)存泄漏的風(fēng)險,上述代碼執(zhí)行分為3個步驟:

1.  new  Widget

2. shared_ptr構(gòu)造

3. computePriority

編譯器不需要必須產(chǎn)生這樣順序的代碼,但“new Widget”必須在std::shared_ptr的構(gòu)造函數(shù)被調(diào)用前執(zhí)行。如果編譯器產(chǎn)生的順序代碼如下:

1.  new  Widget

2. 執(zhí)行computePriority。

3. 執(zhí)行std::shared_ptr的構(gòu)造函數(shù)。

如果執(zhí)行步驟2:computePriority的時候程序出現(xiàn)異常,則在第一步動態(tài)分配的Widget就會泄露了,因為它永遠(yuǎn)不會被存放到在第三步才開始管理它的shared_ptr中

4.2 父類之類智能指針轉(zhuǎn)換

C++中是允許裸指針,因此裸指針之間轉(zhuǎn)換方法同C語言指針強(qiáng)轉(zhuǎn),智能指針轉(zhuǎn)換不能通過上述方法進(jìn)行強(qiáng)轉(zhuǎn),必須通過庫提供轉(zhuǎn)換函數(shù)進(jìn)行轉(zhuǎn)換。C++11的方法是:std::dynamic_pointer_cast;boost中的方法是:boost::dynamic_pointer_cast

#include <memory>  #include <boost/shared_ptr.hpp>  #include <boost/make_shared.hpp>  #include <iostream>  class  Base {    public :    Base(){}    virtual  ~Base() {}  };  class  D :  public  Base {    public :    D(){}    virtual  ~D() {}  };  int  main()  {

//方式一:先初始化子類智能指針,然后調(diào)用dynamic_pointer_cast轉(zhuǎn)換成基類智能指針對象

std::shared_ptr<D> d1 = std::make_shared<D>();  std::shared_ptr<Base> b1 = std::dynamic_pointer_cast<Base>(d1);

//方式二:先new子類D的指針,然后調(diào)用shared_ptr的構(gòu)造函數(shù)初始化基類智能指針

  std::shared_ptr<Base> b2 = shared_ptr<Base>( new  D());    return  0;  }

結(jié)論

方式一和方式二均能夠?qū)崿F(xiàn)基類智能指針指向子類,但建議采用方式1,通過std::make_shared的方式構(gòu)造智能指針,然后進(jìn)行轉(zhuǎn)換;

5. map的安全查找辦法

即map[key]這種寫法,就是會創(chuàng)建元素(且不一定初始化),因此在業(yè)務(wù)邏輯是希望查找的時候,就老老實實用find,不然會有臟數(shù)據(jù)寫入。

6. string 的指針構(gòu)造

std::string 的構(gòu)造方式,除了與其它順序容器相近的方式之外,提供了三種額外的構(gòu)造方式:

string s(cp, n): s 是cp指向的數(shù)組中前n個字符的拷貝,該數(shù)組至少應(yīng)該包含n個字符

string s(s2, pos2):s 是string s2從下標(biāo)pos2開始的字符的拷貝,若pos2>s2.size(),構(gòu)造函數(shù)的行為未定義

string s(s2, pos2, len2):s 是string s2從下標(biāo)pos2開始len2個字符的拷貝,若pos2>s2.size(),構(gòu)造函數(shù)的行為未定義。不管len2的值是多少,構(gòu)造函數(shù)至多拷貝s2.size()-pos2個字符

std::string 未提供 string(cp, pos2, len2) 這種構(gòu)造方式,如果代碼中使用了該方式,最終會將 cp 指向的數(shù)組構(gòu)造成一個string,然后調(diào)用string(s2, pos2, len2)這種構(gòu)造方式。

不提供string(cp, pos2, len2)這種構(gòu)造方式原因在于:使用這種方式構(gòu)造容易出現(xiàn)問題,cp是一個指針,通常使用時,能獲得其數(shù)組長度并檢查傳入?yún)?shù);若傳入兩個參數(shù),容易出現(xiàn)越界。

7. 變量初始化

變量初始化總是沒錯的,不管后面是否會修改該值。尤其是int等內(nèi)建的類型,在類或struct中及容易忽略初始化,使變量成為隨機(jī)值,產(chǎn)生不可預(yù)知的錯誤。變量請初始化!變量請初始化??!變量請初始化!??!

感謝各位的閱讀,以上就是“關(guān)于C++的坑有哪些”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對關(guān)于C++的坑有哪些這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

文章名稱:關(guān)于C++的坑有哪些
網(wǎng)址分享:http://bm7419.com/article30/geigpo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站、ChatGPT、域名注冊動態(tài)網(wǎng)站、網(wǎng)站導(dǎo)航、定制開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站建設(shè)