[英]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.