Здравствуйте, 1234, Вы писали:
1>Здравствуйте, 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>Всё дело в том что для меня стоял вопрос оптимизации по времени, в таких случаял ИМХО можно применять решения который могут немного выходить из общепринятых идиом языка, но в тоже время, они должны оставатся безопасными и универсальными.
1>Вот поэтому я и решил посоветоватся — "Можно ли .... ?" а не "Нужно ли.... ?"
1>>>Тогда возникает второй вопрос. (хотя на самом деле для меня именно он был первым).
1>>>Возможно я чего-то непонимаю, но спускаясь по дереву вызовов stl::vetor::insert()
1>>>я попадаю в конце концов в место где вызывается memmove. Так или иначе вектор сдвигает элементы которые находятся старше предпологаемого индекса вставки. (всем понятно что таких операций нужно старатся избегать в векторе, сейчас вопрос не в этом)
1>>>Тогда получается что вектор нельзя инстанировать ничем иным кроме "старых добрых простых"типов.(POD)
B>>Вектор может использовать специализированные алгоритмы (в том числе и с использованием memcpy/memmove) для POD-типов. Для не-POD он должен выполнять поэлементное копирование. Если у тебя vector<не-POD-тип>::insert использует memmove, то это очень странно. Было бы интересно узнать — что за компилятор, и что за реализация STL.
1>Вы абсолютно правы, я проверил под отладчиком — в случае с классом 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 ...
1>Данный пример иллюстрирует проблему появления висячей ссылки(dead reference), это произойдёт так же в случае если на объект имеются ссылки где-то вне объекта. Эти вещи нужно учитывать, точно так же как если куда-то передаётся адрес какого-то объекта, то нужно гарантировать определённое время жизни этого объекта, что бы непроизошло обращение к уже удалённому объекту.
1>Уточню ещё раз вторую часть вопроса: в чём именно проблема с указателем на таблицу виртуальных функций ?
1>Я никак немогу понять — с самого начала хранятся два указателя — на vptable и на vftable. Сами таблицы находятся где ? Предположим мы передвинули класс, вмести с остальными данными переехали и эти два указателя, но разве их значения поменялись ?
1>Или возможно, Андрей Тарасевич имел в виду своим примером то, что сами таблицы, на которые ссылаются указатели, находятся где-то среди данных класса ? (тогда я вообще непонимаю — где ???) и после сдвига изменяются так же адреса этих таблиц ???
Ошибся, имел ввиду пример не Андрея Тарасевича а Bell-а, т.е. приведённый выше.