在重建一个字符串之前,它是否必须是一个字符串? [英] Is it nessary to destroy a string before constructing it again?
问题描述
作为一个练习,我试图写一个类如 std :: vector
,而不使用模板。它的唯一类型是 std :: string
。
As an exercise, I'm trying to write a class like a std::vector
without using a template. The only type it holds is std::string
.
下面是 strvec。 h
档案:
class StrVec
{
public:
//! Big 3
StrVec():
element(nullptr), first_free(nullptr), cap(nullptr)
{}
StrVec(const StrVec& s);
StrVec&
operator =(const StrVec& rhs);
~StrVec();
//! public members
void push_back(const std::string &s);
std::size_t size() const { return first_free - element; }
std::size_t capacity() const { return cap - element; }
std::string* begin() const { return element; }
std::string* end() const { return first_free; }
void reserve(std::size_t n);
void resize(std::size_t n);
//^^^^^^^^^^^^^^^^^^^^^^^^^^^
private:
//! data members
std::string* element; // pointer to the first element
std::string* first_free; // pointer to the first free element
std::string* cap; // pointer to one past the end
std::allocator<std::string> alloc;
//! utilities
void reallocate();
void chk_n_alloc() { if (size() == capacity()) reallocate(); }
void free();
void wy_alloc_n_move(std::size_t n);
std::pair<std::string*, std::string*>
alloc_n_copy (std::string* b, std::string* e);
};
三个 string *
, element
, first_free
和 cap
可以被认为是: p>
The three string*
, element
, first_free
, and cap
can be thought of as:
[0][1][2][3][unconstructed elements]
^ ^ ^
element first_free cap
实现成员 resize(size_t n)
,我有一个问题。说, v.resize(3)
被调用。因此,指针 first_free
必须向前移动一个位置,并指向 [3]
。像:
When implementing the member resize(size_t n)
, I have a problem. Say, v.resize(3)
is called. As a result the pointer first_free
must be moved forward one place and point to [3]
. Something like:
[0][1][2][3][unconstructed elements]
^ ^ ^
element first_free cap
我的问题是我应该如何处理 [3]
?把它留在那里不变?或者销毁它:
My question is how should I deal with [3]
? Leave it there untouched? Or destroy it like:
if(n < size())
{
for(auto p = element + n; p != first_free; /* empty */)
alloc.destroy(p++);
first_free = element + n;
}
代码 alloc.destroy(somePointer)
必须在这里?
推荐答案
是的,你应该调用 code>在
resize()
中从向量中删除的元素,其参数小于向量的当前大小。这也是 std :: vector
的作用。
Yes, definitely, you should call destroy
on elements that are removed from the vector when resize()
is called with an argument smaller than the current size of the vector. That's what std::vector
does, too.
注意 destroy
只调用这些元素的析构函数;它不会释放任何空格(这是错误的)。
Note that destroy
only calls the destructor on those elements; it does not deallocate any space (which would be wrong).
因为你处理 std :: string
,你可能认为如果你确定以后用一个新值重新初始化相同的 std :: string
对象,你可以没有破坏。但首先,你不能确定一个新的字符串将被存储在同一个地方,其次,对于新的字符串,将创建一个新的对象(使用placement-new,而不是copy-assignment),泄漏内存的前一个字符串(其析构函数不会被调用)。
Since you are dealing with std::string
, you probably think you could do without destruction if you are sure that you re-initialize the same std::string
object later with a new value. But firstly, you can't be sure that a new string will be stored in the same place later, and secondly, for the new string a new object would be created (using placement-new, not copy-assignment), leaking the memory of the previous string (whose destructor would never have been called).
这篇关于在重建一个字符串之前,它是否必须是一个字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!