[英]C++ vector accessing elements
如何從myVector
訪問元素,就像我對數組一樣( for(i = 0; i < n; i++) cout << v[i] << " ";
)
我的代碼:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Month
{
public:
char *name;
int nr_days;
Month(char* c, int nr) : name(c), nr_days(nr){};
~Month() { /* free(name); */}
};
int main()
{
Month January("January", 31);
Month February("February", 28);
Month March("March", 31);
Month April("April", 30);
Month May("May", 31);
Month June("June", 30);
Month July("July", 31);
Month August("August", 31);
Month September("September", 30);
Month Octomber("Octomber", 31);
Month November("November", 30);
Month December("December", 31);
vector<Month> *myVect = new vector<Month>;
myVect->push_back(January);
myVect->push_back(February);
myVect->push_back(March);
myVect->push_back(April);
myVect->push_back(May);
myVect->push_back(June);
myVect->push_back(July);
myVect->push_back(August);
myVect->push_back(September);
myVect->push_back(Octomber);
myVect->push_back(November);
myVect->push_back(December);
for(vector<Month>::const_iterator i = myVect->begin(); i != myVect->end(); i++)
{
/*
Month myMonth = i;
cout << myMonth.name << " " << myMonth.nr_days << endl;
*/
}
free(myVect);
return 0;
}
我想要像foreach算法: foreach(Month in myVect) cout << ...
另一個問題:如果我取消注釋我的行,為什么它會在析構函數中給出運行時錯誤?
好的,這里有很多問題。
您將myVect
聲明為向量的指針。 這是不必要的。 使用向量的一個主要好處是,您不必擔心內存管理,因為vector
會為您執行此操作。 堆棧分配向量,但在內部它堆分配用於存儲它包含的項的內存。
你永遠不會初始化指針。 您正在調用未定義的行為,因為該指針無效。 要初始化指針,請使用new
。 你所擁有的是一個無效的堆棧分配指針,它不指向堆上的vector
。 編輯:我剛剛意識到new
已被刪除,所以你可以忽略這個。 不過,它根本不應該是一個指針。
您正在使用free
來釋放C ++類(您從未分配過以...開頭)。 別。 這不是C,你使用new
和delete
來管理C ++中的內存(必要時!)。 free
不會調用析構函數,它只會釋放一大塊內存。 另一方面, delete
知道如何處理復雜的C ++類型。 切勿將new
/ delete
與malloc
/ free
混合使用。
myVect->begin()
返回一個const_iterator
,而不是一個T
(即,在這種情況下,不是Month
對象)。 通過*
運算符取消引用迭代器將產生當前的迭代對象,因此:
Month myMonth = *i // <--- IMPORTANT!
順便說一句,如果你要經常循環遍歷向量,你可能想要輸入typedef
來減少冗長,即
typedef vector<Month>::const_iterator cmonth_iter;
現在你可以寫了
for(cmonth_iter i = myVect.Begin(); i != myVect.end(); ++i )
{
Month m = *i;
// do stuff with m
}
您可以使用*
運算符使用迭代器訪問元素:
for(vector<Month>::const_iterator i = myVect->begin(); i != myVect->end(); i++)
{
Month myMonth = *i;
cout << myMonth.name << " " << myMonth.nr_days << endl;
}
此外,您永遠不會在代碼中分配vector
。 你不應該在之前沒有從malloc()
收到過的指針上使用free()
。 否則是未定義的行為,並且在調用free()
可能會發生運行時錯誤。
試試這個:
vector<Month> *myVect = new vector<Month>;
...
delete myVect;
如果通過更改以下內容刪除了單位指針錯誤:
vector<Month> *myVect;
至:
vector<Month> myVect;
然后這將工作。 (一旦你定義ostream << Month
)
for(i = 0; i < myVect.size(); i++)
cout << v[i] << " ";
你有一個指針myVect
,但在使用之前從不為它賦值(打開編譯器警告)。 你應該做類似myVect = new vector<Month>()
事情。 (或者不要使它成為指針並改變->
進入.
)。 你的“foreach”實現的其余部分看起來很好。 您也可以使用[]
訪問元素。
你釋放常量字符串,你沒有分配它們,所以你也不需要釋放它們。
您將myVect
聲明為指針但從未分配它,這會給您帶來很多麻煩。 只要放下*
就可以了。
如果你堅持,你可以像使用數組一樣使用索引:
for(int i = 0; i < myVect.size(); i++)
{
Month myMonth = myVect[i];
cout << myMonth.name << " " << myMonth.nr_days << endl;
}
雖然我寧願像你一樣使用迭代器 - 只需要一個簡單的修復:
Month myMonth = *i;
您可以將箭頭運算符與迭代器一起使用...
for(vector<Month>::const_iterator i = myVect->begin(); i != myVect->end(); i++)
{
cout << i->name << " " << i->nr_days << endl;
}
另請注意,使用++i
而不是i++
迭代器更加慣用(原因是i++
需要創建一個將被丟棄的迭代器的副本)。
另請注意,您的代碼是UB(未定義的行為),因為您正在使用指向矢量的指針,但您沒有分配它。 順便說一句,在這種情況下使用指針是無意義的,代碼將是正確和簡單的:
vector<Month> myVect;
myVect.push_back(January);
myVect.push_back(February);
...
for(vector<Month>::const_iterator i = myVect.begin(); i != myVect->end(); ++i)
...
我的建議也是避免嘗試使用編譯器來學習C ++(這是我想要做的事情)。
C ++功能強大但也很復雜,不幸的是在很多方面都非常不合邏輯和不對稱(由於它的演變歷史)。 除此之外,當你犯了一個錯誤(例如沒有在原始代碼中分配向量)時,你不能指望編譯器幫助你,甚至在運行時程序可能會做任何事情,包括顯然按預期工作(最糟糕的事情) 。 這個組合是致命的。
復雜性,不對稱性和缺乏運行時檢查都使C ++無法通過實驗學習......只需獲得一本好書並閱讀它。 這種方式簡單得多。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.