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.
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. 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
.
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).
It adds an item called morris
to the vector cats
IF the vector doesn't already has it!
The std::find
is used to check if the item morris
is in the vector cats
or not. It doesn't has, std::find
returned value would be equal to cats.end()
. After this, everything else is pretty much straight forward.
Assuming the code is correct (like the type and initialization of morris and using pointers for your comparison), the point is to see if morris is in the collection of cats, and if not, to add him to it.
cats is a vector of pointers to Cat objects, not a vector of Cat objects.
This searches the full range of cats(cats.begin() through cats.end()) for an object(pointer to cat) that is equal to morris
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. 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.
First be carefull : your comment is wrong. cats isn't a vector of Cat objects, but a vector of POINTERS to cat objects.
Now, the statement :
std::find(cats.begin(), cats.end(), morris)
implies you have a Cat* somewhere called morris. This statement is going to search the vector, between the two provided iterators (i.e : cats.begin() and cats.end() ) for a pointer to Cat, equall to morris (same address). If none is found, std::find returns the second iterator, so, in your case "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"
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
. There's a difference: Cat
s reside on the stack, are created by doing
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. Then, std::find
is used to search the vector cats
for the newly created object, which will always fail in this code fragment. 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). So if morris
is not found, the code will create a new element at the back of the vector and add morris
to it.
精彩评论