小心使用STL中map的[]操作符
生活随笔
收集整理的這篇文章主要介紹了
小心使用STL中map的[]操作符
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
一個(gè)map就是一個(gè)(關(guān)鍵碼(key),值(value))對(duì)偶的序列,它提供基于關(guān)鍵碼的快速提取操作。也就是說,可以用下標(biāo)運(yùn)算符[]將關(guān)鍵碼作為下標(biāo)去執(zhí)行查找,并返回對(duì)應(yīng)的值。因此可以把map的使用方法想象成有特殊下標(biāo)的數(shù)組。在很多時(shí)候用下標(biāo)運(yùn)算符[]來對(duì)map中的元素進(jìn)行存取是非常方便和簡單的;但是,如果map下標(biāo)運(yùn)算符[]運(yùn)用不得當(dāng),也會(huì)造成意想不到的問題。
我們知道,C++是不檢查下標(biāo)越界的。用超出數(shù)組下標(biāo)范圍的下標(biāo)去訪問數(shù)組元素的錯(cuò)誤會(huì)在運(yùn)行期出現(xiàn),很有可能將程序搞崩潰。對(duì)于map而言,也沒有類似的下標(biāo)越界概念,但是卻有作為下標(biāo)的關(guān)鍵碼(key)在map中不存在的現(xiàn)象。在這種情況下,如果運(yùn)用不得當(dāng),就造成意想不到的問題,而且這種問題是屬于比較隱蔽的問題。如果對(duì)map的下標(biāo)運(yùn)算符[]不是非常了解,將很難發(fā)現(xiàn)問題所在。
比如說有下面的代碼片斷:
// 定義一個(gè)map map<string, string> mapTelDir;
// 用[]操作符可以方便快速的給map添加內(nèi)容 mapTelDir["StarLee"] = "13813131313";
// ...
// 修改關(guān)鍵碼為LiXing的值 // 注意,這里的關(guān)鍵碼在map里面并不存在 if (mapTelDir["LiXing"] == "13913131313") { mapTelDir["LiXing"] = "13513131313"; }
// ...
// 輸出 cout << "The cellhone number of LiXing is: " << mapTelDir["LiXing"] << endl; 上面的代碼看起來似乎沒有任何問題,但是,最后一行的輸出的手機(jī)號(hào)碼卻永遠(yuǎn)為空!原因就是在判斷語句里面對(duì)map的下標(biāo)運(yùn)算符[]的錯(cuò)誤使用。 map的下標(biāo)運(yùn)算符[]的作用是:將關(guān)鍵碼作為下標(biāo)去執(zhí)行查找,并返回對(duì)應(yīng)的值;如果不存在這個(gè)關(guān)鍵碼,就將一個(gè)具有該關(guān)鍵碼和值類型的默認(rèn)值的項(xiàng)插入這個(gè)map。 對(duì)于上面的代碼來說,if (mapTelDir["LiXing"] == "13913131313")這行代碼首先去查詢map中是否有關(guān)鍵碼為LiXing的項(xiàng),結(jié)果發(fā)現(xiàn)沒有該項(xiàng),于是就向map中插入了一項(xiàng)<"LiXing", "">(sting的默認(rèn)值為空字符串)。這就造成if語句的判斷結(jié)果永遠(yuǎn)為false,那樣就不可能修改修改關(guān)鍵碼為LiXing的值。 為了更好的說明這個(gè)問題,可以看一下map下標(biāo)運(yùn)算符[]的實(shí)現(xiàn)代碼:
// 下面的代碼摘自VS2005中的..vcincludemap mapped_type& operator[](const key_type& _Keyval) { ? ?// find element matching _Keyval or insert with default mapped iterator _Where = this->lower_bound(_Keyval); if (_Where == this->end() || this->comp(_Keyval, this->_Key(_Where._Mynode()))) _Where = this->insert(_Where, value_type(_Keyval, mapped_type())); return ((*_Where).second); } map的下標(biāo)操作符[]使用上面的方法定義,使向map里插入值和使用關(guān)鍵碼來訪問相應(yīng)的值變得非常方便而快速。雖然在使用的時(shí)候會(huì)出現(xiàn)有人寫出類似上面那樣的錯(cuò)誤代碼,但是這是程序員的錯(cuò)誤,因?yàn)閷懗稣_的代碼是程序員的責(zé)任。這樣做很符合C++的風(fēng)格:非常靈活,但是要小心使用。
// 定義一個(gè)map map<string, string> mapTelDir;
// 用[]操作符可以方便快速的給map添加內(nèi)容 mapTelDir["StarLee"] = "13813131313";
// ...
// 修改關(guān)鍵碼為LiXing的值 // 注意,這里的關(guān)鍵碼在map里面并不存在 if (mapTelDir["LiXing"] == "13913131313") { mapTelDir["LiXing"] = "13513131313"; }
// ...
// 輸出 cout << "The cellhone number of LiXing is: " << mapTelDir["LiXing"] << endl; 上面的代碼看起來似乎沒有任何問題,但是,最后一行的輸出的手機(jī)號(hào)碼卻永遠(yuǎn)為空!原因就是在判斷語句里面對(duì)map的下標(biāo)運(yùn)算符[]的錯(cuò)誤使用。 map的下標(biāo)運(yùn)算符[]的作用是:將關(guān)鍵碼作為下標(biāo)去執(zhí)行查找,并返回對(duì)應(yīng)的值;如果不存在這個(gè)關(guān)鍵碼,就將一個(gè)具有該關(guān)鍵碼和值類型的默認(rèn)值的項(xiàng)插入這個(gè)map。 對(duì)于上面的代碼來說,if (mapTelDir["LiXing"] == "13913131313")這行代碼首先去查詢map中是否有關(guān)鍵碼為LiXing的項(xiàng),結(jié)果發(fā)現(xiàn)沒有該項(xiàng),于是就向map中插入了一項(xiàng)<"LiXing", "">(sting的默認(rèn)值為空字符串)。這就造成if語句的判斷結(jié)果永遠(yuǎn)為false,那樣就不可能修改修改關(guān)鍵碼為LiXing的值。 為了更好的說明這個(gè)問題,可以看一下map下標(biāo)運(yùn)算符[]的實(shí)現(xiàn)代碼:
// 下面的代碼摘自VS2005中的..vcincludemap mapped_type& operator[](const key_type& _Keyval) { ? ?// find element matching _Keyval or insert with default mapped iterator _Where = this->lower_bound(_Keyval); if (_Where == this->end() || this->comp(_Keyval, this->_Key(_Where._Mynode()))) _Where = this->insert(_Where, value_type(_Keyval, mapped_type())); return ((*_Where).second); } map的下標(biāo)操作符[]使用上面的方法定義,使向map里插入值和使用關(guān)鍵碼來訪問相應(yīng)的值變得非常方便而快速。雖然在使用的時(shí)候會(huì)出現(xiàn)有人寫出類似上面那樣的錯(cuò)誤代碼,但是這是程序員的錯(cuò)誤,因?yàn)閷懗稣_的代碼是程序員的責(zé)任。這樣做很符合C++的風(fēng)格:非常靈活,但是要小心使用。
總結(jié)
以上是生活随笔為你收集整理的小心使用STL中map的[]操作符的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 学习vi和vim编辑器(8):全局替换(
- 下一篇: Linux(CentOS)挂载U盘、移动