Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

std::vector в разных компиляторах

87
24 марта 2008 года
Kogrom
2.7K / / 02.02.2008
Создаю код типа

Код:
#include <iostream>
#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) выдает
 
Код:
constructor 1
destructor 1
constructor 2
destructor 1
destructor 2
destructor 1
destructor 2


Visual c++ 6:
 
Код:
constructor 1
destructor 1
constructor 2
destructor 1
destructor 2

Мне не понятно, почему при добавке второго экземляра класса вызывается деструктор первого, и почему в гнутом компиляторе вызывается столько деструкторов.
5
25 марта 2008 года
hardcase
4.5K / / 09.08.2005
Цитата: Kogrom
Создаю код типа...


Я в С++ не в зуб ногой, но смею предположить, что тут что-то связанное с конструкторами копирования.
Попробуйте явно его определить.

3
25 марта 2008 года
Green
4.8K / / 20.01.2000
Цитата: hardcase
смею предположить, что тут что-то связанное с конструкторами копирования.


Именно!

87
25 марта 2008 года
Kogrom
2.7K / / 02.02.2008
Цитата: hardcase
что-то связанное с конструкторами копирования. Попробуйте явно его определить.



Цитата: Green
Именно!


Докажите. Вот сделал я пустой конструктор копирования и вектор всё равно вызвал деструктор первого объекта, но кроме того, он еще и удалил первый объект, а вместо него поместил копию, с другими параметрами...

Можно конечно сделать конструктор копирования, который запомнит все параметры удаляемого объекта, но деструкторов от этого меньше не станет... Вот мне и непонятно, зачем удаляется первый объект - вроде бы явно я этого не просил.

87
25 марта 2008 года
Kogrom
2.7K / / 02.02.2008
Всё. Разобрался. Причина в неочевидной работе функции push_back(). Что иллюстрируется примером:
Код:
#include <iostream>
#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;
}


при этом на выходе:
Код:
constructor 1
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(тип класса()), создается новый объект, затем он копируется в вектор и уничтожается. Если вектор был не пуст, то, вероятно, создается новая копия вектора в который копируются все объекты старого, а затем старый вектор уничтожается...

Однако...
5
25 марта 2008 года
hardcase
4.5K / / 09.08.2005
Цитата: Kogrom
Вот мне и непонятно, зачем удаляется первый объект - вроде бы явно я этого не просил.

Объекты в C++, в отличие от C# или Java, не являются ссылочными типами, и потому, без использования new (в вашем случае) будут создаваться на стеке.
Как только такой объект перестает быть доступным, вызывается его деструктор (сразу после передачи ячейки в push_back).

87
25 марта 2008 года
Kogrom
2.7K / / 02.02.2008
Больше всего меня теперь печалит, что каждый раз при использовании push_back вызываются деструкторы всех старых элементов вектора...
240
25 марта 2008 года
aks
2.5K / / 14.07.2006
Тут ты не прав. ) Вызываются только потому что не выделил сразу.
87
25 марта 2008 года
Kogrom
2.7K / / 02.02.2008
Цитата: aks
Тут ты не прав. ) Вызываются только потому что не выделил сразу.


А по конкретнее? Чего не выделил?

Я же мысли не читаю, но попробую:) Не выделил память для элементов напимер с помощью команды reserve? Выделял - не помогло... Да и вообще, этот пример я привел для наглядности. В другой моей программе неизвестно, сколько будет элементов.

Поправка.
А вообще, я пригляделся и увидел, что с использованием reserve картинка лучше, но всё равно придется предусматривать специальный конструктор копирования на случай, если элементов будет больше, чем мест зарезервировано...

5
25 марта 2008 года
hardcase
4.5K / / 09.08.2005
Цитата: Kogrom
Не выделил память для элементов напимер с помощью команды reserve?

Нет не методом reserve.
Конструкцией new.

87
25 марта 2008 года
Kogrom
2.7K / / 02.02.2008
Цитата: hardcase
Нет не методом reserve.
Конструкцией new.


Думаю, что вы неправильно прочитали мысли от aks... Если я ошибаюсь, то прошу вас подробнее разъяснить, о чем вы говорите.

Насколько я понимаю, оператор new вернет мне указатель на первый байт выделенной памяти. И что я буду с ним делать? Создавать vector из указателей? И как это поможет? Эх, ваши мысли мне еще труднее читать...

255
26 марта 2008 года
Dart Bobr
1.4K / / 09.04.2004
new вернет вам указатель не на первый байт выделенной памяти, а на первый созданный объект определенного типа!
87
26 марта 2008 года
Kogrom
2.7K / / 02.02.2008
Цитата: Dart Bobr
new вернет вам указатель не на первый байт выделенной памяти, а на первый созданный объект определенного типа!


Согласен. Но насколько я понимаю, это уже не касается обсуждаемой темы. И new мне в приведенном примере совсем не нужен.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог