std::vector в разных компиляторах
#include <vector>
using namespace std;
class cell{
public:
static int counter;
int locCounter;
cell();
~cell();
};
int cell::counter = 0;
cell::cell()
{
counter++;
locCounter = counter;
cout << "constructor " << locCounter << endl;
}
cell::~cell()
{
cout << "destructor " << locCounter << endl;
}
vector<cell> table;
int main()
{
table.push_back(cell());
table.push_back(cell());
}
gcc-g++-3.4.5 (Code::Blocks8.2) выдает
destructor 1
constructor 2
destructor 1
destructor 2
destructor 1
destructor 2
Visual c++ 6:
destructor 1
constructor 2
destructor 1
destructor 2
Мне не понятно, почему при добавке второго экземляра класса вызывается деструктор первого, и почему в гнутом компиляторе вызывается столько деструкторов.
Я в С++ не в зуб ногой, но смею предположить, что тут что-то связанное с конструкторами копирования.
Попробуйте явно его определить.
Именно!
Докажите. Вот сделал я пустой конструктор копирования и вектор всё равно вызвал деструктор первого объекта, но кроме того, он еще и удалил первый объект, а вместо него поместил копию, с другими параметрами...
Можно конечно сделать конструктор копирования, который запомнит все параметры удаляемого объекта, но деструкторов от этого меньше не станет... Вот мне и непонятно, зачем удаляется первый объект - вроде бы явно я этого не просил.
#include <vector>
using namespace std;
class cell{
public:
static int counter;
int locCounter;
bool bCopy;
cell();
cell(const cell &c);
~cell();
};
int cell::counter = 0;
cell::cell()
{
counter++;
bCopy = false;
locCounter = counter;
cout << "constructor " << locCounter << endl;
}
cell::cell(const cell &c)
{
locCounter = c.locCounter;
bCopy = true;
cout << "copy " << c.locCounter << endl;
}
cell::~cell()
{
cout << "destructor " << locCounter << ' ' << bCopy << endl;
}
vector<cell> table;
int main()
{
table.push_back(cell());
table.push_back(cell());
cout << table[0].locCounter << endl;
cout << table[1].locCounter << endl;
}
при этом на выходе:
copy 1
destructor 1 0
constructor 2
copy 1
copy 2
destructor 1 1
destructor 2 0
1
2
destructor 1 1
destructor 2 1
Вывод: при использовании push_back(тип класса()), создается новый объект, затем он копируется в вектор и уничтожается. Если вектор был не пуст, то, вероятно, создается новая копия вектора в который копируются все объекты старого, а затем старый вектор уничтожается...
Однако...
Объекты в C++, в отличие от C# или Java, не являются ссылочными типами, и потому, без использования new (в вашем случае) будут создаваться на стеке.
Как только такой объект перестает быть доступным, вызывается его деструктор (сразу после передачи ячейки в push_back).
А по конкретнее? Чего не выделил?
Я же мысли не читаю, но попробую:) Не выделил память для элементов напимер с помощью команды reserve? Выделял - не помогло... Да и вообще, этот пример я привел для наглядности. В другой моей программе неизвестно, сколько будет элементов.
Поправка.
А вообще, я пригляделся и увидел, что с использованием reserve картинка лучше, но всё равно придется предусматривать специальный конструктор копирования на случай, если элементов будет больше, чем мест зарезервировано...
Нет не методом reserve.
Конструкцией new.
Конструкцией new.
Думаю, что вы неправильно прочитали мысли от aks... Если я ошибаюсь, то прошу вас подробнее разъяснить, о чем вы говорите.
Насколько я понимаю, оператор new вернет мне указатель на первый байт выделенной памяти. И что я буду с ним делать? Создавать vector из указателей? И как это поможет? Эх, ваши мысли мне еще труднее читать...
Согласен. Но насколько я понимаю, это уже не касается обсуждаемой темы. И new мне в приведенном примере совсем не нужен.