开发者

C++ standard template library vector question

开发者 https://www.devze.com 2023-02-14 12:02 出处:网络
Can someone explain in English what is 开发者_运维知识库going on here? std::vector<Cat*> cats; //I get that cats is a vector of Cat objects

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 Cats 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: Cats 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消