l_inc на месте не разрушенного нормально объекта первого типа создается объект другого типа я понял Вашу точку зрения спасибо за разъяснение впринципе создается новый объект по тому же самому адресу и не важно какого типа я смотрел на это иначе из за этого весь сыр-бор я почему то временно абстрагировался от объектов других типов и смотрел на это как на повторный вызов конструктора для одного и того же объета
osox Вот и ладно. Сам уже хотел сказать, что по сути всё, конечно, зависит от уровня абстракции, на котором это рассматривать. Но раз уж мы говорим об объектах в контексте ООП, то и уровень абстракции должен быть выше и не зависеть от низкоуровневых понятий размещения в памяти.
Перефразируя данные l_inc объяснения, вот так будет работать: string_t str("content"); (&str)->~string_t(); // разрушаем старый объект new(&str)string_t("new content");
J0E даже подменяя класс структурой работает главное структуру объекта воссоздать для методов ) Код (Text): struct fake_str{ char *str; size_t len; size_t size; }; fake_str str; new(&str)string_t("content"); ((string_t*)&str)->assign("new content"); ((string_t*)&str)->~string_t(); а что насчет такой записи string_t str = str; ? дергать конструктор по умолчанию ?
Про подмену я не понял, класс и структура суть одно и то же, разница лишь в доступе к членам по умолчанию (class -- private, struct -- public). Твой пример кстати чем-то похож на (анти)паттерн "Паблик Морозов" Должен добавить, что мой код это не пример как надо писать программы. Скорее, оно должно выглядеть в клиентском коде (то есть за приделами библиотек) вот так: string_t str("content"); str.swap( string_t("new content") ); По поводу оператора присваивания. В принципе, можно ответить в 2х словах, что по умолчанию скопируются поля объекта, в результате будет 2 указателя на одни данные... но это довольно сложная тема, база для дальнейшего освоения С++, лучше для начала хотя бы погуглить "глубокое копирование". Это должно быть описано в куче статей, книгах, у Саттера должно быть, но навскидку не вспомню, у Мэйерса в "55 верных советов..." это правило 12, почитай этих авторов, многие вопросы отпадут.
osox new принимает указатель на void и этим всё сказано, подменять можно чем угодно, главное чтобы был размер подходящий. Это что? У Вас такое собирается? Может всё-таки str = str?
J0E string_t str = str; какое глубокое копирование из неинициализированного объекта ?) поэтому как бы и спросил можно присвоить себе же свою же копию неинициализированных полей а можно создать по умолчанию объект Booster скомпилируется поэтому и вопрос в си имя вводится в точке объявления поэтому его можно использовать для инициализации себя самого например
osox Провокация. ^) А вообще Вы смотрели, что в этом случае генерирует компилятор? Один раз вызывается конструктор копирования, причём в качестве аргумента передаётся объект с инициализированными мемберами конструктора копирования. Но есть ещё интересней: str = str = str; Вначале вызывается оператор присваивания, с вообще никак не инициализированным объектом - аргументом, далее уже вызывается конструктор копирования снова с аргументом у которого мемберы инициализированы инициализационным списком конструктора копирования. В общем конструирование происходит всегда только один раз, остальное не более чем трюки, хотя передача оператору присваивания несконструированного объекта это по-моему ахтунг. ^)
правда так я еще не пробовал )) пофиксил баг я расчитывал в операторе присваивания на инициализированный объект позволяло убрать лишнюю проверку на присваивание самому себе а это упуситил из виду все таки пришлось проверку в оператор присваивания дописать сейчас при таком коде string_t str = str = str; первый вызов оператора присваивания если видит что самому себе делает return оставляя объект не инициализированным а потом запустившийся конструктор копий видя что снова самому себе создает по умолчанию строку нулевой длинны видимо из за этого именно надо вставлять проверку в оператор присваивания хотя я где то читал что вовсе не обязательно видимо надеялись на инициализированный объект в операторе присваивания (сделать раз в сто лет дубль дешевле чем каждый раз проверять на присваивание самому себе) а этот случай не рассмотрели вот и у меня так мне было не накладно раз в пол века сделать копию как бы на месте (по сути memmove для одного адреса приемника и источника) чем вставлять проверку в каждый вызов присваивания но все равно пришлось имено из за string_t str = str = str; сейчас посмотрел стандартный string на таком коде string str = str = str = str; он тоже первых два присваивания видя кстати он тоже проверяет на присваивание самому себе что происходит приваивание самому себе оставляет строку в неопределенном состоянии и последний запустившийся конструктор копий создает из этой неинициализированной строки строку по умолчанию и он конструктор копий тоже делает проверку на самого себя как раз чтоб защитится от провокации типа string str = str;
Повторю ещё раз, в операторе присваивания нужно обязательно делать проверку на самого себя, от x = x. В конструкторе копирования не надо, объект конструируется только один раз. В type x = x, он также конструируется один раз. Это рекомендации от основателей С++.
osox Реализация в vs2010 Код (Text): basic_string(const _Myt& _Right) : _Mybase(_Right._Alval) { // construct by copying _Right _Tidy(); assign(_Right, 0, npos); } В assign этот случай как-то обрабатывается, но эта функция ведь и в операторе присваивания используется.
Перефразируй, пожалуйста, вопрос другими словами, не понимаю его смысл. Откуда компилятору может быть известно, что объект-источник не инициализирован? Неужели он будет проверять, не забыл ли ты реализовать в полной мере конструкторы? Говоря про глубокое копирование, я имел ввиду что тебе следует реализовать конструктор копии и оператор присваивания в соответствии с определенными требованиями.
J0E Вот что я там нашёл, правда в другом контексте: По-моему вполне определённое поведение. Правда непонятно зачем такое.