Re[4]: Можно ли перемещать объекты в памяти ?
От: 1234  
Дата: 28.12.04 20:26
Оценка:
Здравствуйте, Bell, Вы писали:

B>Здравствуйте, 1234, Вы писали:


1>>Здравствуйте, Анатолий Широков, Вы писали:


1>>>>memmove, memcpy and e.t.c.


АШ>>>Таким способом можно переносить объекты только POD-типов. Приведенный вами класс POD-типом не являетс

1>>Уточню.
1>>Т.е. вы утверждаете что класс
B>...
1>>копировать используя memcpy/memmove нельзя ?

B>Формально — нельзя, т.к., как уже было сказано, он не является POD-типом. И ограничение это накладывается стандартом языка.

B>Практически же копирование с использованием memcpy/memmove для подобных классов во многих случаях (читай на многих платформах) работать будет. Другой вопрос — стОит ли пренебрегать стандартом...
Я совершенго согласен — стандарт надо блюсти.
Всё дело в том что для меня стоял вопрос оптимизации по времени, в таких случаял ИМХО можно применять решения который могут немного выходить из общепринятых идиом языка, но в тоже время, они должны оставатся безопасными и универсальными.
Вот поэтому я и решил посоветоватся — "Можно ли .... ?" а не "Нужно ли.... ?"


1>>Тогда возникает второй вопрос. (хотя на самом деле для меня именно он был первым).

1>>Возможно я чего-то непонимаю, но спускаясь по дереву вызовов stl::vetor::insert()
1>>я попадаю в конце концов в место где вызывается memmove. Так или иначе вектор сдвигает элементы которые находятся старше предпологаемого индекса вставки. (всем понятно что таких операций нужно старатся избегать в векторе, сейчас вопрос не в этом)

1>>Тогда получается что вектор нельзя инстанировать ничем иным кроме "старых добрых простых"типов.(POD)

B>Вектор может использовать специализированные алгоритмы (в том числе и с использованием memcpy/memmove) для POD-типов. Для не-POD он должен выполнять поэлементное копирование. Если у тебя vector<не-POD-тип>::insert использует memmove, то это очень странно. Было бы интересно узнать — что за компилятор, и что за реализация STL.
Вы абсолютно правы, я проверил под отладчиком — в случае с классом A вызываются кострукторы копирования.


1>>Я бы хотел для себя прояснить этот момент так же с позиции почему может быть опасно двигать в памяти объект если у него нет таблицы виртуальных функций ?

B>У объекта нет таблицы виртуальных функций, у него есть указатель на нее .

B>Вот тебе пример:


B>
B>class bad
B>{
B>   int n_;
B>   int* p_;
B>public:
B>   bad() {p_ = &n_; }
B>   void set(int n) { *p_ = n; }
B>};
B>


B>Думаю, не нужно объяснять, что произойдет при вызове set для объекта, который был перемещен после создания с помощью memmove ...

Данный пример иллюстрирует проблему появления висячей ссылки(dead reference), это произойдёт так же в случае если на объект имеются ссылки где-то вне объекта. Эти вещи нужно учитывать, точно так же как если куда-то передаётся адрес какого-то объекта, то нужно гарантировать определённое время жизни этого объекта, что бы непроизошло обращение к уже удалённому объекту.

Уточню ещё раз вторую часть вопроса: в чём именно проблема с указателем на таблицу виртуальных функций ?
Я никак немогу понять — с самого начала хранятся два указателя — на vptable и на vftable. Сами таблицы находятся где ? Предположим мы передвинули класс, вмести с остальными данными переехали и эти два указателя, но разве их значения поменялись ?
Или возможно, Андрей Тарасевич имел в виду своим примером то, что сами таблицы, на которые ссылаются указатели, находятся где-то среди данных класса ? (тогда я вообще непонимаю — где ???) и после сдвига изменяются так же адреса этих таблиц ???
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.