Lio*_* An 2 c++ copy-constructor
我有以下代码片段
#include <iostream>
#include <vector>
class Move {
private:
int* data;
public:
void set_data_value(int d) {
*data = d;
}
int get_data_value(){
return *data;
}
Move(int d);
Move(const Move &source);
~Move();
};
Move::Move(int d) {
std::cout << "ctor being called" << std::endl;
data = new int;
*data = d;
}
Move::Move(const Move& source) {
std::cout << "copy ctor being called" << std::endl;
data = new int;
*data = *source.data;
}
Move::~Move() {
std::cout << "deleting Move" << std::endl;
delete data;
}
int main() {
Move x{1};
Move y{x};
std::vector<Move> vec;
vec.push_back(x);
vec.push_back(y);
return 1;
}
Run Code Online (Sandbox Code Playgroud)
这是输出:
ctor being called
copy ctor being called
copy ctor being called
copy ctor being called
copy ctor being called
deleting Move
deleting Move
deleting Move
deleting Move
deleting Move
Run Code Online (Sandbox Code Playgroud)
我的问题是:当我只看到 3 个副本时,为什么要调用 4 次复制构造函数?(1个来自Move y{x}和两个来自两个push_back()调用)
你错过了计算向量的重新分配。将此行添加到您的代码中:
int main() {
Move x{1};
Move y{x};
std::vector<Move> vec;
std::cout << "capacity: " << vec.capacity() << "\n";
vec.push_back(x);
std::cout << "capacity: " << vec.capacity() << "\n";
vec.push_back(y);
std::cout << "capacity: " << vec.capacity() << "\n";
return 1;
}
Run Code Online (Sandbox Code Playgroud)
那么可能的输出是:
ctor being called
copy ctor being called
capacity: 0
copy ctor being called
capacity: 1
copy ctor being called
copy ctor being called
deleting Move
capacity: 2
deleting Move
deleting Move
deleting Move
deleting Move
Run Code Online (Sandbox Code Playgroud)
所述vector的产能开始作为0然后随着需要(2或3是常见的因素)。您可以看到,当容量从 1 增加到 2 时,会调用复制构造函数将向量中已经存在的元素复制到内存中的其他位置。
请注意,上面的输出可能会有所不同。分配策略需要进行细微的优化。它push_back具有摊销恒定复杂性的要求,这意味着容量不能线性增长。虽然因素不一定2。一些实现使用3或 不同的因素。