简体   繁体   English

C ++标准模板库矢量问题

[英]C++ standard template library vector question

Can someone explain in English what is going on here? 有人可以用英语解释这里发生了什么吗?

std::vector<Cat*> cats; //I get that cats is a vector of Cat objects

if (std::find(cats.begin(), cats.end(), morris) == cats.end()) {
   cats.push_back(morris);
}

@mlimber has already given one explanation. @mlimber已经给出了一种解释。

I'd explain it a bit differently. 我会以不同的方式解释它。 In plain English, it's a way of taking something really simple: 用简单的英语来说,这是一种非常简单的方法:

 std::set<Cat> cats;

 cats.insert(morris);

and making it slower (linear instead of logarithmic) and considerably harder to read or understand. 并使其变慢(线性而不是对数),并且难以阅读或理解。

Edit: In fairness, I suppose I should add that there are a few reasons you might want to do something like this. 编辑:凭心而论,我想我要补充一点, 还有可能想要做这样的事情的几个原因。 For example, if you really need to know the order in which Cat s were added to the collection, preserving the original order might make some sense. 例如,如果您确实需要知道将Cat添加到集合中的顺序,那么保留原始顺序可能会有些道理。 Likewise, if you're usually using the collection in a way that benefits from them being contiguous in memory, and only rarely adding a new item, it might make more sense to store the data in a vector than an set . 同样,如果通常使用集合的方式是受益于它们在内存中是连续的,并且很少添加新项目,那么将数据存储在vectorset更有意义。

A set , however, is designed to do exactly what's being done here, so a set is the obvious choice (absent compelling reasons to use a vector that just aren't visible in what you've shown). 但是, set目的是完全执行此处要做的事情,因此set是显而易见的选择(没有明显的理由使用在显示的内容中不可见的vector )。

It adds an item called morris to the vector cats IF the vector doesn't already has it! 如果媒介cats还没有的话,它将在媒介cats添加一个名为morris的物品!

The std::find is used to check if the item morris is in the vector cats or not. std::find用于检查morris项目是否在矢量cats It doesn't has, std::find returned value would be equal to cats.end() . 它没有, std::find返回的值将等于cats.end() After this, everything else is pretty much straight forward. 在此之后,其他一切都非常简单。

假设代码是正确的(例如morris的类型和初始化,并使用指针进行比较),重点是看morris是否在猫的集合中,如果不是,则将其添加到猫中。

cats is a vector of pointers to Cat objects, not a vector of Cat objects. cats是指向Cat对象的指针的向量,而不是Cat对象的向量。

This searches the full range of cats(cats.begin() through cats.end()) for an object(pointer to cat) that is equal to morris 这会在cats(cats.begin()到cats.end())的整个范围内搜索等于morris的对象(指向cat的指针)

std::find(cats.begin(), cats.end(), morris)

The return value is an iterator into the vector pointing to the object if it was found, and it returns the end iterator(cats.end()) if it was not found. 返回值是指向对象的向量中的迭代器(如果找到),如果未找到,则返回结束iterator(cats.end())。 With that in mind, this: 考虑到这一点,这是:

if (std::find(cats.begin(), cats.end(), morris) == cats.end())

is a test to see if cats contains that object(morris). 测试猫是否包含该对象(莫里斯)。 And if it doesn't, then it executes this: 如果没有,它将执行以下命令:

cats.push_back(morris);

which puts the object(morris), into the vector. 将对象(morris)放入向量中。

First be carefull : your comment is wrong. 首先要小心:您的评论是错误的。 cats isn't a vector of Cat objects, but a vector of POINTERS to cat objects. cat不是Cat对象的向量,而是POINTERS对cat对象的向量。

Now, the statement : 现在,声明:

std::find(cats.begin(), cats.end(), morris) std :: find(cats.begin(),cats.end(),莫里斯)

implies you have a Cat* somewhere called morris. 表示您在某处有莫里斯猫*。 This statement is going to search the vector, between the two provided iterators (ie : cats.begin() and cats.end() ) for a pointer to Cat, equall to morris (same address). 该语句将在两个提供的迭代器(即cats.begin()和cats.end())之间搜索向量,以寻找指向Cat的指针,该指针等于morris(相同的地址)。 If none is found, std::find returns the second iterator, so, in your case "cats.end()" 如果未找到,则std :: find返回第二个迭代器,因此,在您的情况下为“ cats.end()”

Therefore "if (std::find(cats.begin(), cats.end(), morris) == cats.end()) { cats.push_back(morris); }" means, in plain english "if morris isn't already in the cats vector, put it at the end" 因此,“ if(std :: find(cats.begin(),cats.end(),莫里斯)== cats.end()){cats.push_back(morris);}”的意思是,用简单的英语“如果morris不是不在猫咪矢量中,放在最后”

I'll have a hard time being more specific if we don't know what's bothering you exactly 如果我们不知道到底是什么困扰着我,我会很难说清楚

std::vector<Cat*> cats; //I get that cats is a vector of Cat objects

You get that wrong. 你说错了。 cats is a std::vector of pointers to the class Cat . cats是指向Cat类的指针的std::vector There's a difference: Cat s reside on the stack, are created by doing 区别在于: Cat驻留在堆栈中,是通过以下方式创建的

Cat morris;

and do not have to be deleted. 并且不必删除。 Pointers as in your example, are created by 如您的示例中的指针是由

Cat* morris = new Cat();

and have to be deleted once you're done with it before you throw away the pointer: 并在删除指针后必须将其删除:

delete morris;

I will now add a little code to your example: 现在,我将向您的示例添加一些代码:

Cat* morris = new Cat();

if (std::find(cats.begin(), cats.end(), morris) == cats.end()) {
   cats.push_back(morris);
}

This creates a dynamically allocated object morris of type Cat on the heap. 这将在堆上创建Cat类型的动态分配对象morris Then, std::find is used to search the vector cats for the newly created object, which will always fail in this code fragment. 然后, std::find用于搜索的矢量cats为新创建的对象,这将始终在这段代码失败。 If std::find fails, it returns an iterator to the element one past the last element in the container (which is exactly what std::vector::end() returns). 如果std::find失败,它将向容器中最后一个元素之后的元素返回一个迭代器(这正是std::vector::end()返回的结果)。 So if morris is not found, the code will create a new element at the back of the vector and add morris to it. 因此,如果未找到morris ,则代码将在向量的后面创建一个新元素,并向其中添加morris

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

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