1. 程式人生 > >STL容器map的下標運算子[]

STL容器map的下標運算子[]

在STL中,map是一個關聯式容器,它提供一對一的資料處理能力,即其中每一個元素都是一個鍵值對,通過一個唯一的關鍵字,可以唯一對映到對應的資料值。而map中過載了下標運算子[],通過下標操作,開發人員可以很方便地根據關鍵字獲取到對應的值。雖然使用方便,但是還是有一些地方容易出現問題,值得大家的注意。

       下面程式碼的輸出結果會什麼呢?

map<string, string> mapInfo;
if ("kevin" == mapInfo["name"])
{
    mapInfo["name"] = "man";
}
cout<<mapInfo["name"]<<endl;

       上面程式碼的目的是,判斷mapInfo["name"]的值是否為"kevin",如果是則修改mapInfo["name"]的值為"man",最後輸出mapInof["name"]的值。程式碼看似沒有問題,但是輸出卻永遠為空,原因就是在判斷語句裡面對map的下標運算子[]的錯誤使用。
       map的下標運算子[]的作用是:若key存在,則返回相應的value;若key不存在,則對該key對應的value賦一個對應value型別資料的預設值並返回。
       在上面的程式碼中,對於if ("kevin" == mapInfo["name"])這行程式碼,首先會判斷mapInfo中關鍵字為name的項是否存在,此時程式發現沒有該項,因此會在mapInfo中插入一項("name", ""),此時mapInfo["name"]的值就為空字串,這就導致了if判斷的結果永遠都為false,進不了if程式碼塊裡面修改資料。map下標運算子[]使用固然方便,但是使用不當卻可能出現嚴重的問題,因此需要注意一下。

       下面也是一個關於map下標運算子[]的例子,用於深化對上面結論的記憶:

class Obj
{
public:
	//...
};

map<string, Obj*> mapStr2Obj;
Obj *ptr = mapStr2Obj["abc"];	//ptr等於NULL

       上面程式碼中,map的key是string型別,而value則是Obj*型別,即Obj型別的指標,而mapStr2Obj中並不在關鍵字為"abc"的項,對於mapStr2Obj["abc"],程式會自動插入一項("abc", NULL),此時關鍵字為"abc"的項對應的值是一個空指標,若不小心使用到這個之後指標訪問資料時,就會出現Segmentation fault了。不同編譯器對於指標賦的預設值是不一樣的,當map的value型別是指標的時候,就要注意野指標或空指標問題了。

       從上面的例子可以知道,當需要判斷map中是否存在指定的key值時,就不能直接使用map的下標運算子了,這時候可以使用find函式,如下面程式碼所示:

bool isExist(const string& sKey)
{
    return (mapKV.find(sKey) != mapKV.end());
}

       通過find函式判斷指定的sKey是否在mapKV中,寫起來有點噁心,不過這樣可以避免了錯誤的發生。