2012-05-19 50 views
2

消息是我創建的類。我在傳遞給messageTimeOut(和一些其他函數)的主函數中有一組函數。在messageTimeOut中使用一個itorator,我正在循環它們並訪問不同的成員函數。但是,我只能訪問由迭代器指向的消息的const成員函數。如果我嘗試訪問非const成員函數我得到的錯誤:無法訪問C++中對象的非const成員函數std :: set

「In function 'void messageTimeOut(threadParameters*)': main.cpp:74:33: error: passing 'const Message' as 'this' argument of 'void Message::setTimedOut(bool)' discards qualifiers [-fpermissive].」

這讓我無法訪問一個const Message對象的非const成員函數的意義,但如何去讓這個非const Message對象,所以我可以訪問非常量成員函數並更改消息?由於

我的代碼部分:

 [ . . . ] 

void messageTimeOut(threadParameters* params) 
{ 
    set<Message>::iterator it = params->messages->begin(); 
    [ . . . ] 
    for (; it != params->messages->end(); ++it) 
    { 
     if ((it->createdTime() + RESPONSE_WAIT) < GetTickCount()) 
     { 
      it->setTimedOut(true); // error 
     } 
    } 
    ReleaseMutex(sentQueueMutex); 
} 

    [ . . . ] 

int main() 
{ 
    threadParameters rmparameters; 
    set<Message> sentMessages; 
    [ . . . ] 


    rmparameters.logFile = &logFile; 
    rmparameters.socket = socketDesciptor; 
    rmparameters.messages = &sentMessages; 
     [ . . . ] 

    messageTimeOut(rmparameters); 
     [ . . . ] 

    return 0; 
} 
+0

'threadParameters'成員'messages'的聲明類型是什麼? – dasblinkenlight

回答

9

你不能。

std :: set中的元素總是不變的,因爲否則用戶可以通過修改屬於該集合的元素來修改集合中的排序。

請注意,您調用的函數不會更改順序無關緊要,因爲std :: set無法檢查該函數。

解決此問題的常見方法是從集中刪除元素,對其進行修改,然後重新插入它。 另一種方法是使用地圖,即使這可能會迫使您複製一些數據。

+0

謝謝。這就說得通了。我考慮過使用地圖,但直到構造對象時我的鍵才存在,但我想我可以構造Message對象,然後將其複製到地圖中。 – user1404617

1

你不應該能夠修改一個std ::設置的內容。下面是一個簡化的測試案例:

#include <set> 
#include <iostream> 

void print(int & data) {} 

int main() { 
    std::set<int> objects; 

    objects.insert(3); 
    print(*objects.find(3)); 
} 

鏘將報告以下錯誤:

blah.cc:14:2: error: no matching function for call to 'print' 
     print(*objects.find(3)); 
     ^~~~~ 
blah.cc:4:6: note: candidate function not viable: 1st argument ('const int') would lose const qualifier 
void print(int & data) { 
    ^

因此,它看起來像使用一組是不是在這裏作出正確的決定。

0

集合中的對象是const的,這意味着它們不可變。這裏有一些選擇

1) Create copies of the messages in a new set 
2) Remove the messages, mutate them, and put them back. 
3) Remove the "timeout" field from the message. 

其中我比較喜歡數3.您試圖變異的消息的其實是個「壞代碼味道」。如果您要避免所有數據更改,而是創建一個新結構(例如std :: map),那麼您可以減少線程同步的數量。