让我们扩展您的结构位:
struct T {
T() {
std::cout << "Constructor\n";
}
T(const T&) {
std::cout << "Copy Constructor\n";
}
T(T&&) {
std::cout << "Move Constructor\n";
}
~T() {
std::cout << "Destructor\n";
}
};
和独立的呼叫push_back
方法:
vec.push_back(T()); // 1
std::cout << "--- --- ---\n";
vec.push_back(T()); // 2
std::cout << "--- --- ---\n";
现在输出看起来更完整:
Constructor
Move Constructor
Destructor
--- --- ---
Constructor
Move Constructor
Copy Constructor
Destructor
Destructor
--- --- ---
Destructor
Destructor
第一组:
Constructor
Move Constructor
Destructor
对应于第一push_back
呼叫:
vec.push_back(T()); // 1
输出可能被容易地解密:
Constructor // Create a temporary
Move Constructor // Move a temporary into the internal vector storage
Destructor // Destroy a temporary
第二组:
Constructor
Move Constructor
Copy Constructor
Destructor
Destructor
对应于第二push_back
呼叫:
vec.push_back(T()); // 2
和一个稍微复杂一些:
Constructor // create a temporary
Move Constructor // move it into the newly allocated vector storage
Copy Constructor // copy previously created element into the new storage
Destructor // destroy old storage
Destructor // destroy temporary
在这里,你应该记住,矢量类内部分配的内存中,然后对其进行管理,为所有元素提供enogh空间。因此,如果添加更多元素,则会发生新的分配,并将旧元素复制或移动到新存储中。
在已知大小的情况下,您可以使用reserve
方法,该方法仅为特定数量的元素保留足够的内存。它允许避免不必要的内存重新分配以及在这些重新分配期间向向量中添加新元素(至少在未超过保留大小之前)复制或移动元素。
第三组:
Destructor
Destructor
对应于在节目结束的矢量vec
析构函数调用。
另外还有一个拷贝构造函数;这可能证明照亮。另外,这将有助于在“push_back”调用之前,之后和之间打印某些内容 - 这样,您就可以知道何时发生这些构造函数和析构函数的响应时间。 –
您是否打算一次调用emplace_back并调用一次push_back?没有看到两次调用push_back的点,它与您的标题不匹配。 –
当矢量需要增长其存储空间时,它会分配新的(更大的)内存块,将原始元素复制或移动到新的存储空间,然后销毁原始内存并释放旧内存。额外的析构函数调用可能来自于此。 –