繁体   English   中英

C ++矢量访问元素

[英]C++ vector accessing elements

如何从myVector访问元素,就像我对数组一样( for(i = 0; i < n; i++) cout << v[i] << " ";

我的代码:

#include <iostream>
#include <vector>
#include <string>
using namespace std;

class Month
{
public:
    char *name;
    int nr_days;
    Month(char* c, int nr) : name(c), nr_days(nr){};
    ~Month() { /* free(name); */}
};

int main()
{
    Month January("January", 31);
    Month February("February", 28);
    Month March("March", 31);
    Month April("April", 30);
    Month May("May", 31);
    Month June("June", 30);
    Month July("July", 31);
    Month August("August", 31);
    Month September("September", 30);
    Month Octomber("Octomber", 31);
    Month November("November", 30);
    Month December("December", 31);

    vector<Month> *myVect = new vector<Month>;
    myVect->push_back(January);
    myVect->push_back(February);
    myVect->push_back(March);
    myVect->push_back(April);
    myVect->push_back(May);
    myVect->push_back(June);
    myVect->push_back(July);
    myVect->push_back(August);
    myVect->push_back(September);
    myVect->push_back(Octomber);
    myVect->push_back(November);
    myVect->push_back(December);

    for(vector<Month>::const_iterator i = myVect->begin(); i != myVect->end(); i++)
    {
        /*
        Month myMonth = i;
        cout << myMonth.name << " " << myMonth.nr_days << endl;
        */
    }

    free(myVect);
    return 0;
}

我想要像foreach算法: foreach(Month in myVect) cout << ...

另一个问题:如果我取消注释我的行,为什么它会在析构函数中给出运行时错误?

好的,这里有很多问题。

  1. 您将myVect声明为向量的指针。 这是不必要的。 使用向量的一个主要好处是,您不必担心内存管理,因为vector会为您执行此操作。 堆栈分配向量,但在内部它堆分配用于存储它包含的项的内存。

  2. 你永远不会初始化指针。 您正在调用未定义的行为,因为该指针无效。 要初始化指针,请使用new 你所拥有的是一个无效的堆栈分配指针,它不指向堆上的vector 编辑:我刚刚意识到new已被删除,所以你可以忽略这个。 不过,它根本不应该是一个指针。

  3. 您正在使用free来释放C ++类(您从未分配过以...开头)。 别。 这不是C,你使用newdelete来管理C ++中的内存(必要时!)。 free不会调用析构函数,它只会释放一大块内存。 另一方面, delete知道如何处理复杂的C ++类型。 切勿new / deletemalloc / free混合使用。

  4. myVect->begin()返回一个const_iterator ,而不是一个T (即,在这种情况下,不是Month对象)。 通过*运算符取消引用迭代器将产生当前的迭代对象,因此:


Month myMonth = *i  // <--- IMPORTANT!

顺便说一句,如果你要经常循环遍历向量,你可能想要输入typedef来减少冗长,即

typedef vector<Month>::const_iterator cmonth_iter;

现在你可以写了

for(cmonth_iter i = myVect.Begin(); i != myVect.end(); ++i )
{
    Month m = *i;
    // do stuff with m    
}

您可以使用*运算符使用迭代器访问元素:

for(vector<Month>::const_iterator i = myVect->begin(); i != myVect->end(); i++)
{
    Month myMonth = *i;
    cout << myMonth.name << " " << myMonth.nr_days << endl;
}

此外,您永远不会在代码中分配vector 你不应该在之前没有从malloc()收到过的指针上使用free() 否则是未定义的行为,并且在调用free()可能会发生运行时错误。

试试这个:

vector<Month> *myVect = new vector<Month>;
...
delete myVect;

如果通过更改以下内容删除了单位指针错误:

vector<Month> *myVect;

至:

vector<Month> myVect;

然后这将工作。 (一旦你定义ostream << Month

for(i = 0; i < myVect.size(); i++)
 cout << v[i] << " ";
  1. 你有一个指针myVect ,但在使用之前从不为它赋值(打开编译器警告)。 你应该做类似myVect = new vector<Month>()事情。 (或者不要使它成为指针并改变->进入. )。 你的“foreach”实现的其余部分看起来很好。 您也可以使用[]访问元素。

  2. 你释放常量字符串,你没有分配它们,所以你也不需要释放它们。

您将myVect声明为指针但从未分配它,这会给您带来很多麻烦。 只要放下*就可以了。

如果你坚持,你可以像使用数组一样使用索引:

for(int i = 0; i < myVect.size(); i++)
{        
    Month myMonth = myVect[i];
    cout << myMonth.name << " " << myMonth.nr_days << endl;
}

虽然我宁愿像你一样使用迭代器 - 只需要一个简单的修复:

    Month myMonth = *i;

您可以将箭头运算符与迭代器一起使用...

for(vector<Month>::const_iterator i = myVect->begin(); i != myVect->end(); i++)
{
    cout << i->name << " " << i->nr_days << endl;
}

另请注意,使用++i而不是i++迭代器更加惯用(原因是i++需要创建一个将被丢弃的迭代器的副本)。

另请注意,您的代码是UB(未定义的行为),因为您正在使用指向矢量的指针,但您没有分配它。 顺便说一句,在这种情况下使用指针是无意义的,代码将是正确和简单的:

vector<Month> myVect;
myVect.push_back(January);
myVect.push_back(February);
...
for(vector<Month>::const_iterator i = myVect.begin(); i != myVect->end(); ++i)
  ...

我的建议也是避免尝试使用编译器来学习C ++(这是我想要做的事情)。

C ++功能强大但也很复杂,不幸的是在很多方面都非常不合逻辑和不对称(由于它的演变历史)。 除此之外,当你犯了一个错误(例如没有在原始代码中分配向量)时,你不能指望编译器帮助你,甚至在运行时程序可能会做任何事情,包括显然按预期工作(最糟糕的事情) 。 这个组合是致命的。

复杂性,不对称性和缺乏运行时检查都使C ++无法通过实验学习......只需获得一本好书并阅读它。 这种方式简单得多。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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