有人可以用英文解釋這裏發生了什麼嗎?C++標準模板庫矢量問題
std::vector<Cat*> cats; //I get that cats is a vector of Cat objects
if (std::find(cats.begin(), cats.end(), morris) == cats.end()) {
cats.push_back(morris);
}
有人可以用英文解釋這裏發生了什麼嗎?C++標準模板庫矢量問題
std::vector<Cat*> cats; //I get that cats is a vector of Cat objects
if (std::find(cats.begin(), cats.end(), morris) == cats.end()) {
cats.push_back(morris);
}
@mlimber已經給出了一個解釋。
我會解釋它有點不同。用簡單的英語,這是採取很簡單的東西道:
std::set<Cat> cats;
cats.insert(morris);
,並使其更慢(線性的,而不是對數),並顯着難以閱讀或理解。
編輯:憑心而論,我想我要補充一點,有是你可能想要做這樣的事情的幾個原因。例如,如果您確實需要知道Cat
被添加到集合中的順序,保留原始順序可能會有所幫助。同樣,如果你使用的是集合的方式,從他們的好處是在內存中連續的,只有很少加入新的項目是通常,它可能會更有意義,在vector
數據存儲比set
。
一個set
,然而,是專門做正是什麼正在這裏做,所以set
是顯而易見的選擇(沒有令人信服的理由使用vector
,只是不在你已經證明什麼可見)。
假設代碼是正確的(喜歡的類型和莫里斯的初始化和使用指針您比較),關鍵是看是否莫里斯是貓科動物的集合中,如果沒有,他加入它。
它向矢量cats
添加一個名爲morris
的項目如果矢量還沒有它!
std::find
用於檢查項目morris
是否在矢量cats
中。它沒有,std::find
返回值將等於cats.end()
。在此之後,其他一切都非常簡單。
貓是指向Cat對象的向量的向量,而不是Cat對象的向量。
此搜索的全部範圍的貓(cats.begin()通過cats.end())的一個對象(指針貓)等於莫里斯
std::find(cats.begin(), cats.end(), morris)
返回值是一個指向該對象的向量的迭代器指向該對象(如果找到該對象),並且如果未找到該對象,則返回結束迭代器(cats.end())。考慮到這一點,這一點:
if (std::find(cats.begin(), cats.end(), morris) == cats.end())
是一個測試,看看貓包含對象(莫里斯)。而如果不是這樣,那麼它執行該:
cats.push_back(morris);
這使所述對象(莫里斯),到載體中。
首先要小心:您的評論是錯誤的。貓不是貓對象的矢量,而是貓對象的指針矢量。現在
,語句:
的std ::發現(cats.begin(),cats.end(),莫里斯)
意味着你有一隻貓*的地方叫莫里斯。這個語句將在兩個提供的迭代器(即:cats.begin()和cats.end())之間搜索向量,作爲指向Cat的指針,等同於morris(相同的地址)。如果沒有找到,std :: find返回第二個迭代器,所以,在你的情況「cats.end()」
因此「if(std :: find(cats.begin(),cats.end() ,morris)== cats.end()){cats.push_back(morris);}「意思是用普通英語」如果morris不在貓的載體中,就把它放在末尾「
I'如果我們不知道究竟是什麼讓你感到困難的話,我們會很難做到這一點
std::vector<Cat*> cats; //I get that cats is a vector of Cat objects
你弄錯了。 cats
是指向類Cat
的指針的std::vector
。有一個區別:Cat
小號駐留在棧上,由做
Cat morris;
創建並沒有被刪除。指針在你的榜樣,是由
Cat* morris = new Cat();
創建,有一次你用它做刪除你扔掉指針之前:
delete morris;
我現在將添加一些代碼來你的例子:
Cat* morris = new Cat();
if (std::find(cats.begin(), cats.end(), morris) == cats.end()) {
cats.push_back(morris);
}
這在堆上創建Cat
型的動態分配對象morris
。然後,std::find
用於搜索矢量cats
中新創建的對象,該對象在此代碼片段中始終會失敗。如果std::find
失敗,它會將迭代器返回到容器中最後一個元素之後的元素1(這正是std::vector::end()
返回的值)。因此,如果找不到morris
,代碼會在矢量的後面創建一個新元素,並向其添加morris
。
+1對我從來沒有使用std :: set感到羞恥 - 我現在要感謝你指出了這一點(應該不是std :: set,雖然?) –
Tom
2011-03-03 19:26:25
所以插入到一個集合將檢查確定它是否已經存在? – sol 2011-03-03 19:39:55
@sol:是的。 'set :: insert(t)':「當且僅當容器中沒有元素時才插入t,其鍵值等於t的鍵值。」在'set'的情況下,鍵是對象。 – 2011-03-03 19:46:46