Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> порядок удаления объектов в std::vector, деструкторы вызываются слева направо 
V
    Опции темы
zim22
Дата 4.2.2010, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 24
Всего: 69



Я думал, что порядок вызовов деструкторов обратен порядку вызова конструкторов.
Т.е. если создаётся сначала объект А, а потом объект Б, то при выходе из области видимости будет сначала удалён объект Б, а потом А.

В случае создания С-массива объектов так и происходит.
Код

struct S;

int main() 
{
  S arr[3];
}

Цитата

S 0
S 1
S 2
~S 2
~S 1
~S 0



Однако в случае std::vector элементы удаляются, начиная с индекса 0 и до конца. Это не противоречит Стандарту?
Код

#include <iostream>
#include <vector>

struct S {
  S() : i(cnt++) { 
    std::cout << "S " << i << std::endl; 
  }
  S(const S &rhs) : i(cnt++) { 
    std::cout << "S(const &S) " << i << std::endl;
  }
  ~S() { 
    std::cout << "~S " << i << std::endl;
  }
  static int cnt;
  int i;
};

int S::cnt = 0;


int _tmain(int argc, _TCHAR* argv[])
{
  std::vector<S> vs(3);

  return 0;
}

Цитата

S 0
S(const &S) 1
S(const &S) 2
S(const &S) 3
~S 0
~S 1
~S 2
~S 3



Это сообщение отредактировал(а) zim22 - 4.2.2010, 13:57


--------------------
PM MAIL   Вверх
mes
Дата 4.2.2010, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(zim22 @  4.2.2010,  12:39 Найти цитируемый пост)
Я думал, что порядок вызовов деструкторов обратен порядку вызова конструкторов.

к объектам размещенным в куче это высказывание не относится  smile 



--------------------
PM MAIL WWW   Вверх
zim22
Дата 4.2.2010, 16:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 24
Всего: 69



Цитата(mes @  4.2.2010,  15:00 Найти цитируемый пост)
к объектам размещенным в куче это высказывание не относится

это понятно, что динамические объекты будут удалены принуждённо, используя delete.

но тем не менее в Мейерсе "More effective C++" (Item 4) удаление объектов в куче производится от последнего к первому. 
я вот и задумался, почему он именно в таком порядке удалял. и пришёл только к одной логически обоснованной позиции: удаление от последнего к первому велось для того, чтобы не нарушать Стандарт, в котором возможно где-то сказано, что вызов деструкторов должен быть обратен вызову конструкторов.
Код

void *rawMemory =  operator new[](10*sizeof(EquipmentPiece));
EquipmentPiece *bestPieces =  static_cast<EquipmentPiece*>(rawMemory);

for (int i = 0; i < 10; ++i)
  new (&bestPieces[i]) EquipmentPiece( ID Number );

// destruct the objects in bestPieces in the inverse
// order in which they were constructed
for (int i = 9; i >= 0; --i)
  bestPieces[i].~EquipmentPiece();

// deallocate the raw memory
operator delete[](rawMemory);









--------------------
PM MAIL   Вверх
azesmcar
Дата 4.2.2010, 16:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата

The deleteexpression
will invoke the destructor (if any) for the object or the elements of the array being
deleted. In the case of an array, the elements will be destroyed in order of decreasing address (that is, in reverse order of the completion of their constructor; see 12.6.2).


Добавлено через 4 минуты и 14 секунд
Цитата(zim22 @  4.2.2010,  13:39 Найти цитируемый пост)
Однако в случае std::vector элементы удаляются, начиная с индекса 0 и до конца. Это не противоречит Стандарту?

а кто сказал что то, что сказано в стандарте по поводу оператора delete [] касается вектора?
Код

#include <iostream>
#include <vector>
struct S {
    S() : i(cnt++) { 
        std::cout << "S " << i << std::endl; 
    }
    S(const S &rhs) : i(cnt++) { 
        std::cout << "S(const &S) " << i << std::endl;
    }
    ~S() { 
        std::cout << "~S " << i << std::endl;
    }
    static int cnt;
    int i;
};

int S::cnt = 0;

int main()
{
    S * s = new S[3];
    delete [] s;
}

с оператором delete [] компилятор прекрасно справляется.

PM   Вверх
tolgamrab
Дата 4.2.2010, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 1.2.2010
Где: г. Смоленск

Репутация: нет
Всего: нет



Цитата(zim22 @  4.2.2010,  16:18 Найти цитируемый пост)
удаление от последнего к первому велось для того, чтобы не нарушать Стандарт


пересмотрел стандарт на контейнеры (глава 23), нет там такого. Стандартизируется только сложность методов и интерфейсы. Так что у Мейерс, вероятно, решил перенести на динамический контейнер правила из другой области C++, чтобы избежать тонких проблем при использовании этого контейнера. Попытка встроить в алгоритм использование такой "фичи" ни к чему хорошему не приведет.
PM MAIL ICQ   Вверх
zim22
Дата 4.2.2010, 17:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 24
Всего: 69



Цитата(azesmcar @  4.2.2010,  15:38 Найти цитируемый пост)
а кто сказал что то, что сказано в стандарте по поводу оператора delete [] касается вектора?

никто и не говорил.
но в другой книге (совпадение?) элементы тоже удаляются в обратном порядке.

в той книге (С++ Primer 4th edition, параграф 18.1.2) они создавали свой класс Vector
и там была функция reallocate, которая вызывалась тогда, когда при вставке нового элемента в векторе не хватало места и необходимо было выделить кусок памяти побольше.
Код

...
// construct copies of the existing elements in the new space
uninitialized_copy(elements, first_free, newelements);

// destroy the old elements in reverse order
for (T *p = first_free; p != elements; /* empty */ )
  alloc.destroy(--p);

у меня вопрос: им что, всем делать нечего? почему они "извращаются" и удаляют в обратном порядке элементы?
***
здесь сказано, что в ISO C++ standard для std::vector порядок удаления не установлен (unspecified). Т.е. как хотите - так и реализовывайте.
а здесь частично объясняется зачем удалять, начиная с последнего элемента:
Цитата

That's continuation of reverse order of destructor invokation filosophy of C++


Это сообщение отредактировал(а) zim22 - 4.2.2010, 18:34


--------------------
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0492 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.