繁体   English   中英

C++ 在类中访问向量

[英]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();


}

output 的屏幕截图

我期待我可以从另一个 class 访问 class 中的矢量元素

mljcheck方法中是一个新的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM