[英]C++ accessing vectors in classes
我是 C++ 的初學者,我的問題是:為什么我在向該向量添加元素后嘗試訪問另一個 class 中的向量元素時,為什么我在 class 中的向量是空的?
我有一個 class,例如class1 ,這個 class 有一個字符串類型的向量和一個成員 function,它使用 push_back() 向向量添加元素,另一個成員 function 有一個字符串類型的參數,如果參數在向量,否則返回 false。 現在,如果我寫另一個 class class2 ,它有一個名為 valid 的字符串類型向量和一個名為 function 的成員,檢查它是否從輸入中讀取一個字符串,我們有一個class1 object,我們可以訪問 class1 成員 function 來檢查這個輸入是否是在來自class1的向量中,但在class2中看起來像我在class1中具有元素的向量是空的。 我究竟做錯了什么?
這是代碼:
class abc{
private:
vector<string> words;
public:
void seta() {
string s;
cout << "word: ";
cin >> s;
words.push_back(s);
}
bool word_check(string a) {
for(string b : words) {
if(b == a) {
return true;
}
}
return false;
}
};
class b{
private:
vector<string> valid;
public:
void check() {
abc mlj;
string k;
cout << "Enter word to check: ";
cin >> k;
bool w = mlj.word_check(k);
while(w == false) {
cerr << "invalid input, try again: ";
cin.clear();
cin.ignore(INT_MAX, '\n');
cin >> k;
}
valid.push_back(k);
}
};
int main() {
abc vkk;
vkk.seta();
vkk.seta();
vkk.seta();
b pla;
pla.check();
}
我期待我可以從另一個 class 訪問 class 中的矢量元素
mlj
在check
方法中是一個新的local object,里面沒有任何單詞。 您所有的單詞都輸入到main
function 中,並存儲在vkk
中。 所以你需要通過 object 來check
。
為此,修改接收引用的方法
void check(const abc & mlj)
{
string k;
cout << "Enter word to check: ";
cin >> k;
bool w = mlj.word_check(k);
// ...
valid.push_back(k);
}
現在,這會給你一個編譯器錯誤,因為abc::word_check
是一個非常量方法。 我們還通過將const
說明符添加到方法定義來解決這個問題。 當我們這樣做時,讓我們也接受字符串作為 const 引用,並且在迭代向量時也使用引用。 這避免了不必要的字符串復制。
bool word_check(const string& a) const
{
for(const string& b : words) {
if(b == a) {
return true;
}
}
return false;
}
需要注意的是,這也可以通過<algorithm>
中的標准庫提供的std::find
來實現:
bool word_check(const string& a) const
{
return std::find(words.begin(), words.end(), a) != words.end();
}
讓我們回到您的main
,並更新它以正確調用check
:
int main() {
abc vkk;
vkk.seta();
vkk.seta();
vkk.seta();
b pla;
pla.check(vkk); // <-- pass vkk here
}
另一件需要注意的事情是你的check
循環被打破了。 如果w
為 false,則循環將永遠不會終止,因為您再也不會更新w
。 相反,你這樣做怎么樣:
while ((cin >> k) && !mlj.word_check(k))
{
cerr << "invalid input, try again: ";
cin.ignore(INT_MAX, '\n');
cin >> k;
}
if (cin)
{
valid.push_back(k);
}
這會同時做幾件事......
首先,它確保 stream 實際上讀取了一個字符串並且沒有輸入一些錯誤 state(例如流結束)。 在一般情況下,從標准輸入讀取字符串不會導致設置錯誤位,因此您也不需要cin.clear()
。
其次,每次循環都會調用word_check
,只有檢查失敗才進入循環體。 循環結束后,我們再次測試stream是否正常,如果是則說明我們讀取了一個單詞並通過了檢查。
進行這些更改,您至少就可以擁有一個工作程序了。 我還可以做出其他挑剔的選擇,但我可能已經做了太多,所以我會停下來! 編碼愉快!
在你給出的示例代碼中,你創建了兩個相同的class的獨立對象,每個對象在memory中占據不同的空間並且彼此完全獨立。 因此,mlj object 完全獨立於 vkk object,到目前為止還沒有插入任何東西。 為了讓您的代碼正常工作,我建議您對其進行以下更改。 即,將 class abc 賦給 class b 的輸入:
class abc {
private:
vector<string> words;
public:
void seta() {
string s;
cout << "word: ";
cin >> s;
words.push_back(s);
}
bool word_check(string a) {
for (string b : words) {
if (b == a) {
return true;
}
}
return false;
}
};
class b {
private:
vector<string> valid;
public:
void check(abc mlj) {
string k;
cout << "Enter word to check: ";
cin >> k;
bool w = mlj.word_check(k);
while (w == false) {
cerr << "invalid input, try again: ";
cin.clear();
cin.ignore(INT_MAX, '\n');
cin >> k;
}
valid.push_back(k);
}
};
int main() {
abc vkk;
vkk.seta();
vkk.seta();
vkk.seta();
b pla;
pla.check(vkk);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.