2015-06-27 69 views
0
int &HTable::operator[](const string &key){ 
    int hashVal = hash(key); 
    list<City> citylist = _pht->at(hashVal); 
    std::list<City>::iterator it = citylist.begin(); 
    for (; it != citylist.end(); it++){ 
     std::cout << "came_inside" << endl; 
     City ob = (*it); 
     if (ob.city == key){ 
      return ob.population; 
     } 
    } 
    City newcity(key,0); 
    citylist.push_front(newcity); 
    _pht->erase(_pht->begin() + hashVal); 
    _pht->insert(_pht->begin() + hashVal, citylist); 
    return newcity.population; 
} 

我的班級:數組下標運算符重載在C++

class HTable 
{ 
    public: 
     HTable(int); 

     int &operator[ ](const string &); 
     void print () const; 
     int size () const; 

    private: 
     int _size; 
     vector< list<City> > *_pht; 

     int hash(const string &) const; 
}; 

我的問題是,當我嘗試使用此:

HTable fl_cities(n);      // hash table with n lists 

fl_cities["abcd"] = 1000; 
fl_cities["abc"] = 111; 
fl_cities["abcdefdf"] = 111; 

cout << fl_cities["abc"] << endl; // return 0 
cout << fl_cities["abcdefdf"] << endl; // return 0 
cout << fl_cities["abcd"] << endl; // return 0 

我沒有得到預期值,這表明0因爲我分配0然後返回值。它是假設返回指針,然後當我分配值應該去那裏,但它不起作用。

我已經試過這個簡單的int數組的運算符,它在這種情況下工作完美。但是在這個問題中,列表中的矢量不起作用。

+0

原因在於你的'operator []'創建了一個'list ',它是vector元素的副本,在該列表中創建一個'City'的副本,然後返回一個對成員的引用那個「城市」。這意味着你的'operator []'(以混淆的方式)返回一個臨時參考,當'main()'使用它時不會存在。這會導致未定義的行爲。 – Peter

回答

1

[]執行以下操作:

如果散列鍵。然後,它複製該散列處的元素列表,在那裏搜索關鍵字,如果找到它就返回一個引用,並銷燬您創建的列表的副本。這將返回一個懸而未決的參考,訪問是未定義的。

如果它無法在列表中找到關鍵字,它將生成一個本地條目,將該條目複製到列表副本中,刪除與關鍵字對齊的哈希向量中的列表,將列表複製回散列矢量,然後返回對本地條目的引用。然後銷燬本地條目,就像清單副本一樣。

未定義的行爲來自讀取對您銷燬的本地條目的引用。

你需要梳理值與引用的區別,並注意生命週期和副本。

citylist更改爲參考。

刪除函數底部的擦除/插入。最後一行返回citylist.front().population

+0

謝謝@Yakk。它現在有效。我弄錯了。欣賞它。 – Novice

+0

@novice好!您有沒有migrw =從像Python/java/c#/等參考隱式語言吃任何機會? – Yakk