2010-01-26 150 views
0

我在我的C++應用程序中使用了兩個類。代碼如下:將項目添加到C++列表中

class MyMessageBox 
{ 
public: 
    void sendMessage(Message *msg, User *recvr); 
    Message receiveMessage(); 
    list<Message> dataMessageList; 
}; 

class User 
{ 
public: 
    MyMessageBox *dataMsgBox; 
}; 

msg是指向Message類的派生類對象的指針。我已經實現了函數SendMessage如下:

void MyMessageBox::sendMessage(Message *msg, User *recvr) 
{ 
    Message &msgRef = *msg; 
    recvr->dataMsgBox->dataMessageList.push_back(msgRef); 
} 

當我編譯這段代碼,我得到以下錯誤: 未定義的參考`虛表的消息」。請幫我解決這個問題。

謝謝, Rakesh。

+0

你使用什麼編譯器? – Yacoby 2010-01-26 11:47:26

+0

我正在使用GCC編譯器gcc 4 – 2010-01-26 11:48:00

+0

Message類的實現是什麼?另外,由於您使用的是std :: list ,所以一旦您將它們push_back在列表中,派生的Message對象將被切片爲純文本消息對象。改爲使用列表。 – TheFogger 2010-01-26 11:50:51

回答

4

我不知道你想用msgRef做什麼,但這是錯誤的。你是否是前Java程序員?

如果Message是衍生品Message的基類,則需要在列表中存儲指針。將list<Message>更改爲list<Message*>;並且push_back(msgRef)應該變成push_back(msg),完全刪除msgRef代碼。

另外,作爲一個風格問題,把大量的->操作員連在一起是個壞主意。在這種情況下,最好在User上實施一種方法,將Message添加到自己的列表中並調用該方法。

+0

謝謝Kylotan。我改變了你的代碼,現在它編譯好了。 – 2010-01-26 12:01:25

+2

@Rakesh K - 如果你有一個列表,不要忘記你需要額外的清理代碼。列表析構函數將_not_刪除指針指向的元素。您必須自己手動刪除它們,或者(推薦)使用類似boost :: shared_ptr <>的方式將它們作爲值對象來處理,當最後一次引用對象被銷燬時它們將被銷燬。如果您不使用shared_ptr或自己清理列表,則最終會發生資源泄漏。 – 2010-01-26 13:11:35

0

我認爲這是一個稍微有些人爲的錯誤消息,提示您沒有爲您的消息類實現構造函數。看看herehere on SO ...

既然你想一個指針傳遞給對象的列表,編譯器可能抱怨它沒有辦法Message*轉換爲Message。按照Kylotan的建議,嘗試將列表更改爲Message*列表。

這是編譯還是鏈接錯誤?

+0

不是在這種情況下。在這裏實現* virtual *構造函數沒有什麼好的理由。 – PierreBdR 2010-01-26 11:58:06

0

如果要處理子類消息,則需要使用消息指針列表而不是消息對象,並管理其生存期。爲了方便起見,我建議使用boost庫使其

list< boost::shared_ptr<Message> > datamessageList 

。 (不要冒犯,但你需要閱讀更多關於C++和指針的文章:它看起來像你嘗試了代碼的各種排列,直到你得到了編譯好的東西......)

1

對於初學者,如果你想要在一個標準的C++容器中存儲一個多態對象,你應該存儲一個指向該對象的指針而不是基類的對象。如果你不這樣做,你會遇到對象切片問題。另外,請自己幫忙,並將指針包含在智能指針中以防止資源泄漏 - 我會推薦boost :: shared_ptr <>。

鑑於您沒有向我們展示Message的代碼,我們只能猜測出問題所在。因爲它是指一個虛函數表,機會是:

  • 你沒有宣佈任何消息的分類成員爲virtual。與析構函數開始將是一個不錯的主意
  • 你忘了對包含的信息

編譯代碼順便說一個目標文件鏈接,創造sendMessage()額外的參考是沒有必要的,恕我直言,沒有按」 t確實有助於可讀性。只需在您對push_back()的調用中取消引用msg指針即可。

0

正如有些人提出更好的解決方案:檢查std :: queue或std :: deque以排隊您的消息。所以現在你有:

std::queue<std::tr1::shared_ptr<Message> > dataMessageQueue;