大约十年前,我对C ++编码有点了解,但从未真正爱上它。但是我现在需要我的一个项目使用c ++(所以我对c ++有点了解,但我不是高深的专家)。我浏览了我的旧笔记和代码片段,并让代码完成了我想要的工作—除了一件事:

#include <iostream>
#include <vector>
#include <string>

using namespace std;

class B
{
    private:
        string ns;

    public:
        B(string ms) {ns = ms;}
        string gets() {return ns;}
};

class A
{
    private:
        vector<B> nb;

    public:
        A(vector<B> mb) {nb = mb;}
        vector<B> getb() {return nb;}
};

int main(int argc, char **argv)
{
    B b0 = B("zero");
    B b1 = B("one");
    B b2 = B("two");
    B b3 = B("three");
    A a = A({b0, b1, b2, b3});

    cout << endl << endl;

    for(auto it = a.getb().begin(); it != a.getb().end(); ++it)
        cout << it->gets() << " ";

    return 0;
}


运行此代码(g ++ -std = c ++ 11 main.cpp)会导致


  抛出'std :: bad_alloc'实例后调用终止
  what():std :: bad_alloc中止(核心转储)


错误。这已经很奇怪了,因为这基本上只是我的笔记中的一个副本(但是,它在笔记中返回整数而不是字符串)。如果我改为让函数返回ns.c_str(),它几乎可以正常工作,我得到


  齐一二三


有趣的是,这只是在循环中发生。使用(a.getb().begin())->gets()给我正确的值(“零”)。这种奇怪行为的解释是什么?

最佳答案

getb()a.getb().begin()中的每个a.getb().end()返回原始向量的单独副本。将一个向量的迭代器与另一个向量的迭代器进行比较是不好的。

您可以将getb()方法更改为类似这样的方法。

const vector<B>& getb() const {return nb;}

现在,begin()end()调用将在相同的向量上工作。

或使用更c ++ 11友好的基于范围的for循环:

for (var b in a.getb()) {
    cout << b.gets() << " ";


哪个为您执行.begin().end()++

如果您绝对要使用老式的for循环,而不是更改您的getb()方法,则还可以执行以下操作:

auto b_copy = a.getb();
for(auto it = b_copy.begin(); it != b_copy.end(); ++it)
    cout << it->gets() << " ";

10-07 19:35