简体   繁体   English

C ++正确使用向量迭代器

[英]C++ using vector iterator correctly

I'm new to C++ and I have a vector of doctors. 我是C ++的新手,并且有很多医生。
I add a new doctor with the following code: 我用以下代码添加新医生:

void DoctorAdmin::setDoctor(std::string lastname, std::string forename,
 Person::Sex sex){

    //Create new doctor
    Doctor* doc = new Doctor(lastname, forename, sex);

    //insert at the end of the vector
    doctors.push_back(doc);
}

Then I want to show their information on the console: 然后,我想在控制台上显示他们的信息:

void DoctorAdmin::showDoctors(){

cout << "Doctors:" << endl;
cout << "Name" << "\t\t\t" << "Forename" << "\t\t\t" << "Sex" << endl;

for (vector<Doctor*>::iterator i = doctors.begin(); i != doctors.end(); i++){

    Doctors* doc = doctors.at(i);
    cout << doc->getName() << "\t\t\t" << doc->getForename() << "\t\t\t" 
         << doc->getSex() << endl;
}

After doing it like this I get two Errors: 这样做后,我得到两个错误:

E0304   No instance of overloaded function "std::vector<_Ty, _Alloc>::at [mit _Ty=Doctors *, _Alloc=std::allocator<Doctors *>]" matches the argument list.

// and

C2664   "Doctors *const &std::vector<Doctors *,std::allocator<_Ty>>::at(const unsigned int) const" : cannot convert from Argument "std::_Vector_iterator<std::_Vector_val<std::_Simple_types<_Ty>>>" in "const unsigned int" 

How do I use the vector iterator correctly to avoid this? 如何正确使用向量迭代器来避免这种情况?

An iterator is not index-like, it is pointer-like. 迭代器不像索引,而是像指针。

for (vector<Arzt*>::iterator doc = aerzte.begin(); doc != aerzte.end(); doc++)
{
    cout << (*doc)->getName() << "\t\t\t" << (*doc)->getVorname() << "\t\t\t" 
         << (*doc)->getGeschlecht() << endl;
}

It seems like you are confused as to when you need to new things too. 似乎您也对何时需要new事物感到困惑。 Most of the time you don't need new 大多数时候,您不需要new

vector<Arzt> aerzte;

void ArztAdmin::anlegenArzt(std::string name, std::string vorname, Person::Geschlecht geschlecht){
    // Create new doctor at the end of the vector
    aerzte.emplace_back(name, vorname, geschlecht);   
}

You can also directly bind references as loop variables 您还可以将引用直接绑定为循环变量

for (Arzt & doc : aerzte)
{
    cout << doc.getName() << "\t\t\t" << doc.getVorname() << "\t\t\t" 
         << doc.getGeschlecht() << endl;
}

The at function requires an index, but a vector<Arzt*>::iterator is not an index, neither semantically nor technically. at函数需要一个索引,但是从语义上或技术上来说, vector<Arzt*>::iterator都不是索引。 An iterator points directly to an element , whereas an index represents the distance between a container's start and the element in a container that allows random element access. 迭代器直接指向元素 ,而索引表示容器的开始位置与容器中允许随机元素访问的元素之间的距离。

Because an iterator points directly to an element, the at function isn't even necessary in your loop. 因为迭代器直接指向元素,所以循环中甚至不需要at函数。 *i yields the element: *i产生元素:

Arzt* doc = *i;

Beginning with C++11, the code for such simple loops can be written in a shorter way using auto : 从C ++ 11开始,可以使用auto以较短的方式编写此类简单循环的代码:

for (auto i = aerzte.begin(); i != aerzte.end(); i++){

The compiler knows what type i really is because it knows what begin() returns. 编译器知道i实际上是什么类型,因为它知道begin()返回什么。

Even better, use a range-based loop: 更好的是,使用基于范围的循环:

for (auto doc : aerzte){
    cout << doc->getName() << "\t\t\t" << doc->getVorname() << "\t\t\t" 
         << doc->getGeschlecht() << endl;
}

And while we're at it, don't use dynamic memory allocation when you don't have to. 而且,当我们使用它时,不必使用动态内存分配。 This isn't Java or C#; 这不是Java或C#; new is dangerous territory in C++ and should be avoided: new在C ++中是危险领域,应避免:

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

struct Arzt
{
    Arzt(std::string const& name, std::string const& vorname) :
        name(name),
        vorname(vorname)
    {
    }

    std::string name;
    std::string vorname;
    // Geschlecht omitted for brevity's sake
};

int main()
{
    std::vector<Arzt> aerzte;

    Arzt doc1("foo", "bar");
    Arzt doc2("foo", "bar");
    Arzt doc3("foo", "bar");

    aerzte.push_back(doc1);
    aerzte.push_back(doc2);
    aerzte.push_back(doc3);

    for (auto const& arzt : aerzte)
    {
        std::cout << arzt.name << ' ' << arzt.vorname << '\n';
    }
}

As you are no longer iterating over pointers but over larger objects, const& should be used in the for loop. 由于您不再遍历指针而是遍历更大的对象,因此const&应该在for循环中使用。

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

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