[英]C++ Vector unable to push_back
我一生都無法找出導致此錯誤的原因:
資料來源:
#include <iostream>
#include <vector>
using namespace std;
class taco {
private:
//Classes
class ingredient {
private:
//Ingredients have basic flavors
//Flavors should total 100% for ingredients
float sweet;
float sour;
float bitter;
float salt;
float umami; //Difficult taste to define, generally synonomous with savory or meaty
//Ingredients have flavor modifiers
bool hot; //Is the ingredient served Hot or Cold?
short intensity; //How bland is the ingredient (100% for flavorful, 0% for flavorless)
short moist; //100% for liquid (sauces etc) higher % to represent juice meats or fruits
public:
ingredient ( float sweet = 30.0, float sour = 0.0, float bitter = 0.0, float salt = 60.0, float umami = 10.0, bool hot = false, float intensity = 30.0, float moist = 25.0) {
//Default ingredient is flour tortilla
this->sweet = sweet; //Grains typically have a sugary tast even though it might not be very strong
this->sour = sour;
this->bitter = bitter;
this->salt = salt; //Tortillas do have a salt content as well, it might not be very strong but this 60% represents a total out of the 100% flavor, the strength is determined by intensity
this->umami = umami; //Most foods have at least small amounts of umami. Its umami that gives two foods with similliar tastes, different flavors.
this->hot = hot; //While a steamed tortilla is good, tortillas can be served either steamed or unsteamed. We default to not steamed as steamed tortilla will be a different ingredient
this->intensity = intensity; //Tortillas are relatively bland. They have a destinctive taste and can affect the overall taste of a taco but the taste is not very intense
this->moist = moist; //Flour tortillas are not generally moist but if there was no water content they would be brittle and unbending. Steamed tortillas and corn tortillas are usually more moist.
}
};
//Vectors
vector<ingredient> ingredients; //Create vector to store ingredients
public:
taco () {
ingredient defIngredient();
this->ingredients.push_back(defIngredient);
}
void foo ( ingredient bar ) {
this->ingredients.push_back(bar);
}
};
int main ( void ) {
return 0;
}
我對向量的經驗基本上沒什么,但是我無法弄清楚為什么它說不能轉換類型。 該向量被定義為類型成分,而我嘗試向其推送的值是同一類型。
編輯:我很抱歉,這不是我要發布的錯誤,我已對其進行了更新。 先前的代碼是在玩玩之后。 我確實意識到類型int hat代碼有區別。
ingredients
是一個vector<ingredient*>
-如您所見,它包含指向ingredient
指針 。 您正在試圖推回bar
,這是一個ingredient
本身。
您不能只使用&bar
(它可以編譯,但無法工作),因為bar
是本地對象,很快就會被銷毀。
相反,您應該只將ingredient
對象存儲在向量中:
vector<ingredient> ingredients;
您有指針向量,而您嘗試push_back的不是指向成分的指針,而是成分對象。 從更改vector<ingredient*> ingredients;
vector<ingredient> ingredients;
。
向量實際上具有錯誤的類型。 您可以將向量定義為vector<ingredient*>
(包含指向成分的指針的向量),但是不是按值而是按值來推動指針。
您可以通過將向量更改為vector<ingredient>
(省略星號)或使函數foo帶有指針來修復代碼。
常見錯誤:
ingredient defIngredient();
沒有用空的構造函數初始化。
采用
ingredient defIngredient;
代替。 這是一個非常討厭並且容易被忽視的“一例外”。
為了不再次陷入陷阱,請使用C ++ 11並始終使用新的{...}
-syntax進行初始化 。
ingredient defIngredient{};
無論如何。 考慮在構造函數中使用初始化程序 :
class ingredient {
private:
...
ingredient()
: sweet(30.0), sour(0.0), bitter(0.0), salt(60.0), umami(10.0),
hot(false), intensity(30.0), moist(25.0)
{}
或使用C ++ 11 成員初始化器
class ingredient {
private:
float sweet = 30.0f;
float sour = 0.0f;
float bitter = 0.0f;
float salt = 60.0f;
float umami = 10.0f;
bool hot = false;
short intensity = 30;
short moist = 25;
}; // no default c'tor needed anymore
說到C ++ 11:
更好的舊C ++是:
void foo ( const ingredient& bar ) {
this->ingredients.push_back(bar);
}
這樣可以為您節省一個對象的副本。
在C ++ 11中,您可以對參數使用值語義(這始終是一件好事),並且仍然保存副本-但是使用上面的const-ref,您已經90%了。
void foo ( ingredient bar ) {
this->ingredients.emplace_back(std::move(bar));
}
也許可以使您對C ++有所助益。
您的向量包含指針:
vector<ingredient*> ingredients; //Create vector to store ingredients
但是您正在嘗試推動一個對象:-
void foo ( ingredient bar ) {
this->ingredients.push_back(bar);
您可能想要向量來存儲實際對象,而不是指向它們的指針?
當使用用戶定義類型作為vector的元素時,應提供默認構造函數和復制構造函數。
使用push_back時,第一步是使用默認構造函數創建對象,第二步是將currect元素復制到vecotor中的新對象,這效率不高,向量是一種更好的方法
使用new運算符創建對象時,不必擔心局部變量
taco () {
ingredient *defIngredient = new ingredient();
this->ingredients.push_back(defIngredient);
}
記得刪除析構函數中的對象
~ingredient ()
{
for(vector<ingredient*>::iterator vec_iter = ingradients.begin();
vec_iter != ingradients.end(); ++ vec_iter)
{
if(*vec_iter)
{
delete *vec_iter;
*vec_iter = NULL;
}
}
}
注意:當對象頻繁復制並在其他類中使用時,可以應用shared_ptr。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.