2013-08-19 170 views
1

我在創建結構向量時遇到問題。在我的函數AddApp中,我無法將新分配的結構「push_back」到vector中。我收到錯誤消息「無效的參數」。我環顧四周,看看是否有人有類似的問題,但沒有任何幫助。任何人都可以指出我的邏輯有什麼缺陷?謝謝。向量的結構C++

class AppHolder 
{ 
private: 
    struct Info 
    { 
    int refNumber; 
    string name; 
    string link; 
    }; 

vector<Info> dataBase; 

public: 
    void AddApp(int ,string ,string); 
}; 

void AppHolder::AddApp(int R, string N, string L) 
{ 
Info *newApp = new Info; 
newApp -> name = N; 
newApp -> link = L; 
newApp -> refNumber = R; 

dataBase.push_back(newApp); 
} 
+2

你怎麼知道'Type'從'型*'不同,對不對? – elmigranto

+2

您嘗試推回一個指針,但該矢量模板是針對您的結構的實例。 – ypnos

+0

好吧,我現在明白了。感謝回覆,這有所幫助。 – Samuel

回答

6

你的代碼失敗的原因是std::vector<Info>::push_back要求你通過它的對象類型Info,但你通過Info*

我們可以通過直接使用Info對象,而不是使用指針解決這new ED變量:

void AppHolder::AddApp(int R, string N, string L) 
{ 
    Info newApp; 
    newApp.name = N; 
    newApp.link = L; 
    newApp.refNumber = R; 
    dataBase.push_back(newApp); 
} 

Info* newApp = new Info;聲明一個指針信息,並與Info類型的動態創建的對象,的地址對其進行初始化,其必須稍後刪除,否則析構函數將不會被調用,並且內存不會被釋放。

Info newApp;聲明一個類型爲Info的自動變量,在作用域的末尾調用析構函數,並釋放其內存。

在現代C++中使用帶指針的new是因爲它需要指針的手工delete,它是異常不安全的(如果在刪除之前拋出異常,資源不會被刪除)並涉及編寫大量代碼(複製構造函數,複製賦值運算符,析構函數,移動構造函數,移動賦值運算符)以確保您的類可以正常工作。但是,有些情況下需要使用指針(將實例派生類存儲在容器中),在這種情況下,您想使用智能指針,它可以爲您管理資源。

0

,必須關閉此:

vector<Info> dataBase; 

到這一點:

vector<Info*> dataBase; 

,只要你想的push_back一個指針,向量聲明爲對象。

+2

這將**方式**更好地存儲對象,而不是指針。 – juanchopanza

+0

-1:在容器中存儲原始指針總是失敗(涉及編寫代碼以滿足三/五規則,異常不安全代碼)。總有比手動更好的選擇。 – milleniumbug

2

聲明

vector<Info> dataBase; 

宣告需要Info對象的載體。在初始化器,

Info *newApp = new Info; 
newApp -> name = N; 
newApp -> link = L; 
newApp -> refNumber = R; 

dataBase.push_back(newApp); 

聲明dataBase.push_back(newApp);試圖在指針推到Info結構到向量(但你的載體想要的對象,沒有對象的指針)。

所以,你要麼需要decalre指針的載體Info結構 - vector<Info *> - 並記住自由每個指針在類的析構。或者,只需在堆棧上創建一個Info結構(即一個實際的對象),並將其推入到vector中(這將在vector中創建一個struct的副本 - 將在您的情況下使用默認的struct copy構造函數,這很好,因爲struct不包含指針等或任何需要不支持深層複製)。

後一種方法更安全,因爲你不必記得釋放任何東西,而且在這種情況下更有效,很可能,因爲雖然你複製的結構,你不昂貴的系統調用到OS來進行內存分配。

2

您的編譯器抱怨的原因是您將dataBase定義爲Info實例的向量,並且您試圖將指針推向Info實例。

改變vector<Info>聲明vector<Info*>是單向的,或改變AddApp方法:

void AppHolder::AddApp(int R, string N, string L) 
{ 
    Info newApp; 
    newApp.name = N; 
    newApp.link = L; 
    newApp.refNumber = R; 

    dataBase.push_back(newApp); 
} 

正如其他人所指出的,在C++中使用的new氣餒,所以保持你的容器定義是首選。將您的實施更改爲使用正確的類型。

一個評論者闡明瞭爲什麼一個在C++中使用new時應該謹慎。

+2

並不是不鼓勵使用'new'(它存在的原因),但是應該小心地分配內存以防止內存泄漏(以及其他難以發現/修復內存相關的錯誤)。通常,確保內存得到正確清理的一個好方法就是使用'unique_ptr'(或其他智能指針包裝器模板)而不是原始指針。也就是說,我比不必要的內存分配版本更喜歡這個特殊問題的非堆回答。 –