简体   繁体   中英

C++ accessing vectors in classes

i am a beginner in C++ and my question is: why my vector in a class is empty when i try to access that vector elements in another class after i added elements to that vector?

i have a class for example class1 and this class has a vector of type string and a member function which adds elements to the vector with push_back() and another member function which has an argument of type string and it returns true if the argument is in the vector or else it returns false. now if i write another class class2 and it has a vector of type string named valid and a member function named check that it reads a string from input and we have a class1 object that we can access the class1 member function to check if this input is in the vector from class1 but looks like in class2 the vector i had in class1 with elements is empty. what am i doing wrong?

here is code:

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();


}

screenshot of the output

i was expecting that i can access vector elements in class from another class

mlj is a new local object in the check method, and it contains no words. All your words were input in the main function and are stored in vkk . So you need to pass that object to check .

To do that, modify the method to receive a reference

void check(const abc & mlj)
{
    string k;
    cout << "Enter word to check: ";
    cin >> k;
    bool w = mlj.word_check(k);
    // ...
    valid.push_back(k);
}

Now, this will give you a compiler error, because abc::word_check is a non-const method. Let's also fix that by adding the const specifier to the method definition. While we're at it, let's accept the string as a const reference too, and also use references while iterating over the vector. This avoids unnecessary string copying.

bool word_check(const string& a) const
{
    for(const string& b : words) {
        if(b == a) {
            return true;
        }
    }
    return false;
}

It should be noted that this can also be achieved with std::find which is provided by the standard library in <algorithm> :

bool word_check(const string& a) const
{
    return std::find(words.begin(), words.end(), a) != words.end();
}

Let's circle back to your main , and update that to call check correctly:

int main() {
    abc vkk;
    vkk.seta();
    vkk.seta();
    vkk.seta();

    b pla;
    pla.check(vkk);  // <-- pass vkk here
}

One other thing to note is your loop in check is broken. If w is false, then the loop will never terminate because you never update w again. How about instead you do this:

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);
}

This does a couple of things at once...

First, it ensures the stream has actually read a string and not entered some error state (such as end of stream). Under ordinary conditions, reading strings from standard input will not result in error bits being set, so you also don't need cin.clear() .

Second, it calls word_check every time around the loop, and only enters the loop body if the check fails. After the loop, we test once again that the stream is good, and if so then it means we read a word and it passed the check.

Make these changes, and you're at least on the way to having a working program. There are other nit-picks I could make, but I may have done too many already so I'll stop! Happy coding!

In the code that you have given as an example, you have created two separate objects of the same class, each of which occupies a different space in memory and is completely independent of each other. Therefore, the mlj object is completely independent from the vkk object and nothing has been inserted in it so far. For your code to work properly I suggest you make the following change to it. That is, give the class abc to the input of 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);


}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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