Josuttis在他的书The C ++ standard library中建议空()超过 container.size()> 0.他说它实际上更有效率。 鉴于此实现,这可能不是真的。 2.标准描述清楚,它表现得像擦除(开始,结束)。这好像它会抹掉第一个元素, 复制所有的元素,依此类推,这显然非常低效。假设一些更合理的事情在掩护下发生是否安全? erase()不会逐个删除元素:整个范围被删除复制/移动以下元素。然后删除未使用的尾随元素。如果ABCDEFGH的前三个元素被删除,通常会发生的步骤是:使用赋值运算符复制DEFGH - > DEFGHFGH 尾随元素被破坏 - > DEFGH hmm..IIRC,它们不是。 必须注意擦除尾随元素(即FGH)。 祝福, Sharad I am trying to understand under what circumstances destructors get calledwith std::vector. I have an application in which I will put real objects,not just pointers, in the vector.1. The standard says that empty() has constant complexity. If it actuallycalled the destructor for each object, it seems to me it would havelinear complexity. Does empty() call the destructor for each object in thecontainer? If yes, why is it described as having constant commplexity?If no, that seems like a problem too.2. The standard describes clear by saying that it behaves likeerase(begin, end). That seems as if it would erase the first element, copyingall succedding elements over it, and so on, which is obviously veryinefficient. Is it safe to assume something more reasonable is happeningunder the covers?3. Does erase call the destructor for the elements erased?More properly, I guess I should ask if the elements freed at the end afterbeing moved over erased items are cleared. I''d probably only be erasingthe whole vector or its last element.As I''m writing this I realize I may have a basic confusion, and thatconstructors and destructors are only called at the beginning and endof the vector''s life (and when its capacity expands). The rest of thetime elements are either in use or not, with the behavior of the assignmentoperator being key. Is that what''s really going on?I''m interested both in what can and can''t be inferred from the standard, andin what current compiler practice on different platforms is--in other words,what''s safe to assume in portable code. 解决方案 "Ross Boylan" <Ro********@stanfordalumni.org> wrote... I am trying to understand under what circumstances destructors get called with std::vector. I have an application in which I will put real objects, not just pointers, in the vector. 1. The standard says that empty() has constant complexity. If it actually called the destructor for each object, it seems to me it would have linear complexity. Does empty() call the destructor for each object inthe container? If yes, why is it described as having constant commplexity? If no, that seems like a problem too.''empty'' is not the same as ''clear''. Do not confuse the two. For C++library containers, ''empty'' is an adjective, not a verb. 2. The standard describes clear by saying that it behaves like erase(begin, end). That seems as if it would erase the first element,copying all succedding elements over it, and so on, which is obviously very inefficient. Is it safe to assume something more reasonable is happening under the covers?Absolutely. When semantics are explained, it doesn''t mean that theimplementation is precisely the same. Do not confuse semantics andimplementation. 3. Does erase call the destructor for the elements erased?Yes. More properly, I guess I should ask if the elements freed at the end after being moved over erased items are cleared.I am not sure I completely understand the sentence, but elements canbe freed even in the middle of erasing, during the move. std::vectoris a tricky container, it has to reallocate and move things all thetime, so the old elements will get destroyed right after new copies ofthem are made. I''d probably only be erasing the whole vector or its last element.Don'' make no difference, they are still gonna get destroyed. Hafta. As I''m writing this I realize I may have a basic confusion, and that constructors and destructors are only called at the beginning and end of the vector''s life (and when its capacity expands).....and when you insert or remove an element in the middle. IOW, everytime elements get moved around. The rest of the time elements are either in use or not, with the behavior of theassignment operator being key. Is that what''s really going on?Plenty. Why not trace all the constructor and destructor calls? It''sfun and it''s educational. It''s educational fun. I''m interested both in what can and can''t be inferred from the standard,and in what current compiler practice on different platforms is--in otherwords, what''s safe to assume in portable code.Nothing is safe to assume except what''s said in the Standard.V"Ross Boylan" <Ro********@stanfordalumni.org> wrote in messagenews:pa****************************@stanfordalumni .org... I am trying to understand under what circumstances destructors get called with std::vector. I have an application in which I will put real objects, not just pointers, in the vector. 1. The standard says that empty() has constant complexity. If it actually called the destructor for each object, it seems to me it would have linear complexity. Does empty() call the destructor for each object inthe container? If yes, why is it described as having constant commplexity? If no, that seems like a problem too.A conforming implementation of empty() is: return this->size() > 0;This function does not empty the vector ( unlike clear() ): it onlyreturns a boolean that indicates whether the container is empty or not. 2. The standard describes clear by saying that it behaves like erase(begin, end). That seems as if it would erase the first element,copying all succedding elements over it, and so on, which is obviously very inefficient. Is it safe to assume something more reasonable is happening under the covers?erase() does not remove elements one by one: the whole range is "removed"by copying/moving the following elements over it. Then the unused trailingelements are removed.Say if the first three elements of ABCDEFGH are erased, steps that willtypically happen are:DEFGH are copied down using the assignment operator --> DEFGHFGHThe trailing elements are destroyed --> DEFGH 3. Does erase call the destructor for the elements erased?Yes. More properly, I guess I should ask if the elements freed at the end after being moved over erased items are cleared. I''d probably only be erasing the whole vector or its last element.Which means you can call clear() and pop_back(), respectively,instead of erase(). As I''m writing this I realize I may have a basic confusion, and that constructors and destructors are only called at the beginning and end of the vector''s life (and when its capacity expands). The rest of the time elements are either in use or not, with the behavior of theassignment operator being key. Is that what''s really going on?The capacity of a vector is only allocated as raw memory.The number of constructed objects within the vector is always equal tothe value returned by vector::size(). I''m interested both in what can and can''t be inferred from the standard,and in what current compiler practice on different platforms is--in otherwords, what''s safe to assume in portable code.No ''ghost'' objects can be constructed by std::vector, given than:- the element contained in an std::vector may not have a defaultconstructor- keeping hidden copies of elements that have been erased would haveunexpected effects -- and is not allowed.hth, Ivan-- http://ivan.vecerina.com/contact/?subject=NG_POST <- e-mail contact form"Ivan Vecerina" <pl*****************@ivan.vecerina.com> wrote in messagenews:c0**********@newshispeed.ch... "Ross Boylan" <Ro********@stanfordalumni.org> wrote in message news:pa****************************@stanfordalumni .org... I am trying to understand under what circumstances destructors get called with std::vector. I have an application in which I will put real objects, not just pointers, in the vector. 1. The standard says that empty() has constant complexity. If it actually called the destructor for each object, it seems to me it would have linear complexity. Does empty() call the destructor for each object in the container? If yes, why is it described as having constant commplexity? If no, that seems like a problem too. A conforming implementation of empty() is: return this->size() > 0; This function does not empty the vector ( unlike clear() ): it only returns a boolean that indicates whether the container is empty or not.Josuttis in his book "The C++ standard library" recommends empty() overcontainer.size() > 0. He says it is _usually_ more efficient.Given this implementation this might not be true. 2. The standard describes clear by saying that it behaves like erase(begin, end). That seems as if it would erase the first element, copying all succedding elements over it, and so on, which is obviously very inefficient. Is it safe to assume something more reasonable is happening under the covers? erase() does not remove elements one by one: the whole range is "removed" by copying/moving the following elements over it. Then the unused trailing elements are removed. Say if the first three elements of ABCDEFGH are erased, steps that will typically happen are: DEFGH are copied down using the assignment operator --> DEFGHFGH The trailing elements are destroyed --> DEFGHhmm..IIRC, they are not.One must take care to erase the trailing elements (i.e FGH).Best wishes,Sharad 这篇关于关于std库容器上的析构函数的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-16 03:34