簡體   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