Официальный ответ: В случае вашего класса std :: vector может делать столько копий, сколько им нравится, поскольку в стандарте нет ограничений.
Что, вероятно, происходит: копия выполняется при передаче объекта в качестве параметра и снова, когда вектор изменяется внутри.
Разве это неэффективно? Да
Как его улучшить?
Либо удалите пользовательский деструктор и конструктор копирования, либо определите собственный конструктор перемещения и оператор копирования. Первый случай позволяет компилятору создавать свои собственные операции перемещения, которые они предоставляют.
После того, как компилятор может сделать вывод, что ваш класс въезда известно, операции StD :: вектор становится намного более эффективными, и вы увидите ровно один экземпляр (потому что вы заставляете компилятор сделать один называя Child
называется Item1
)
Edit: рассмотрим пример
#include <stdio.h>
#include <vector>
#include <iostream>
class Child
{
public:
Child();
Child(const Child &item);
Child(Child&& item);
Child& operator=(const Child &item);
Child& operator=(Child&& item);
~Child();
private:
std::string name() const {
return std::string { _zombie ? "zombie" : "child" };
}
bool _zombie = false;
};
Child::Child()
{
std::cout << "constructing " << name() << "\n";
}
Child::Child(const Child &item)
{
std::cout << "copy-constructing " << name() << "\n";
}
Child::Child(Child &&item)
{
std::cout << "move-constructing " << name() << "\n";
item._zombie = true;
}
Child& Child::operator=(const Child &item)
{
_zombie = false;
std::cout << "assigning " << name() << "\n";
return *this;
}
Child& Child::operator=(Child &&item)
{
item._zombie = true;
_zombie = false;
std::cout << "move-assigning " << name() << "\n";
return *this;
}
Child::~Child()
{
std::cout << "destructing " << name() << "\n";
}
using namespace std;
int main(int argc, const char * argv[])
{
{
std::vector<Child> v;
Child item1;
v.push_back(item1);
}
cout << endl;
{
std::vector<Child> v;
v.push_back(Child{});
}
cout << endl;
{
std::vector<Child> v;
Child item1;
v.push_back(std::move(item1));
}
cout << endl;
return 0;
}
пример вывода:
constructing child
copy-constructing child
destructing child
destructing child
constructing child
move-constructing child
destructing zombie
destructing child
constructing child
move-constructing child
destructing zombie
destructing child
_Questions, ищущий помощь для отладки («почему этот код не работает?») должен включают в себя желаемое поведение, конкретную проблему или ошибку и кратчайший код, необходимый для воспроизведения его в самом вопросе. Вопросы без четкого описания проблемы не полезны для других читателей. См.: [Как создать минимальный, полный и проверенный пример ] (http://stackoverflow.com/help/mcve). По крайней мере покажите свое объявление класса 'Child'. –
У нас, по крайней мере, отсутствует определение' Child'. – Shoe
Я создал тестовый проект, и я не вижу поведения, которое вы предлагаете. Он просто создает и копирует один. http://coliru.stacked-crooked.com/a/5460f09cdc665fd8 –