Здравствуйте, 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. Сами таблицы находятся где ? Предположим мы передвинули класс, вмести с остальными данными переехали и эти два указателя, но разве их значения поменялись ?
Или возможно, Андрей Тарасевич имел в виду своим примером то, что сами таблицы, на которые ссылаются указатели, находятся где-то среди данных класса ? (тогда я вообще непонимаю — где ???) и после сдвига изменяются так же адреса этих таблиц ???