[C++] вопрос связанный с конструктором

Тема в разделе "LANGS.C", создана пользователем osox, 3 окт 2010.

  1. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    l_inc
    на месте не разрушенного нормально объекта первого типа создается объект другого типа я понял Вашу точку зрения спасибо за разъяснение впринципе создается новый объект по тому же самому адресу и не важно какого типа
    я смотрел на это иначе из за этого весь сыр-бор я почему то временно абстрагировался от объектов других типов и смотрел на это как на повторный вызов конструктора для одного и того же объета
     
  2. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    osox
    Вот и ладно. :) Сам уже хотел сказать, что по сути всё, конечно, зависит от уровня абстракции, на котором это рассматривать. Но раз уж мы говорим об объектах в контексте ООП, то и уровень абстракции должен быть выше и не зависеть от низкоуровневых понятий размещения в памяти.
     
  3. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    Перефразируя данные l_inc объяснения, вот так будет работать:

    string_t str("content");
    (&str)->~string_t(); // разрушаем старый объект
    new(&str)string_t("new content");
     
  4. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    J0E
    даже подменяя класс структурой работает главное структуру объекта воссоздать для методов )
    Код (Text):
    1. struct fake_str{
    2.     char *str;
    3.     size_t len;
    4.     size_t size;
    5. };
    6.  
    7. fake_str str;
    8. new(&str)string_t("content");
    9. ((string_t*)&str)->assign("new content");
    10. ((string_t*)&str)->~string_t();
    а что насчет такой записи string_t str = str; ?
    дергать конструктор по умолчанию ?
     
  5. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    Про подмену я не понял, класс и структура суть одно и то же, разница лишь в доступе к членам по умолчанию (class -- private, struct -- public). Твой пример кстати чем-то похож на (анти)паттерн "Паблик Морозов" :)

    Должен добавить, что мой код это не пример как надо писать программы. Скорее, оно должно выглядеть в клиентском коде (то есть за приделами библиотек) вот так:

    string_t str("content");
    str.swap( string_t("new content") );


    По поводу оператора присваивания. В принципе, можно ответить в 2х словах, что по умолчанию скопируются поля объекта, в результате будет 2 указателя на одни данные... но это довольно сложная тема, база для дальнейшего освоения С++, лучше для начала хотя бы погуглить "глубокое копирование". Это должно быть описано в куче статей, книгах, у Саттера должно быть, но навскидку не вспомню, у Мэйерса в "55 верных советов..." это правило 12, почитай этих авторов, многие вопросы отпадут.
     
  6. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    osox
    new принимает указатель на void и этим всё сказано, подменять можно чем угодно, главное чтобы был размер подходящий.

    Это что? У Вас такое собирается? Может всё-таки str = str?
     
  7. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    J0E
    string_t str = str;
    какое глубокое копирование из неинициализированного объекта ?)
    поэтому как бы и спросил можно присвоить себе же свою же копию неинициализированных полей а можно создать по умолчанию объект
    Booster
    скомпилируется поэтому и вопрос в си имя вводится в точке объявления поэтому его можно использовать для инициализации себя самого например
     
  8. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    osox
    Провокация. ^) А вообще Вы смотрели, что в этом случае генерирует компилятор? Один раз вызывается конструктор копирования, причём в качестве аргумента передаётся объект с инициализированными мемберами конструктора копирования. Но есть ещё интересней: str = str = str; Вначале вызывается оператор присваивания, с вообще никак не инициализированным объектом - аргументом, далее уже вызывается конструктор копирования снова с аргументом у которого мемберы инициализированы инициализационным списком конструктора копирования.

    В общем конструирование происходит всегда только один раз, остальное не более чем трюки, хотя передача оператору присваивания несконструированного объекта это по-моему ахтунг. ^)
     
  9. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    правда так я еще не пробовал )) пофиксил баг я расчитывал в операторе присваивания на инициализированный объект позволяло убрать лишнюю проверку на присваивание самому себе а это упуситил из виду все таки пришлось проверку в оператор присваивания дописать
    сейчас при таком коде string_t str = str = str;
    первый вызов оператора присваивания если видит что самому себе делает return оставляя объект не инициализированным а потом запустившийся конструктор копий видя что снова самому себе создает по умолчанию строку нулевой длинны видимо из за этого именно надо вставлять проверку в оператор присваивания хотя я где то читал что вовсе не обязательно видимо надеялись на инициализированный объект в операторе присваивания (сделать раз в сто лет дубль дешевле чем каждый раз проверять на присваивание самому себе) а этот случай не рассмотрели
    вот и у меня так мне было не накладно раз в пол века сделать копию как бы на месте (по сути memmove для одного адреса приемника и источника) чем вставлять проверку в каждый вызов присваивания но все равно пришлось имено из за string_t str = str = str;
    сейчас посмотрел стандартный string на таком коде string str = str = str = str; он тоже первых два присваивания видя кстати он тоже проверяет на присваивание самому себе что происходит приваивание самому себе оставляет строку в неопределенном состоянии и последний запустившийся конструктор копий создает из этой неинициализированной строки строку по умолчанию и он конструктор копий тоже делает проверку на самого себя как раз чтоб защитится от провокации типа string str = str;
     
  10. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Повторю ещё раз, в операторе присваивания нужно обязательно делать проверку на самого себя, от x = x. В конструкторе копирования не надо, объект конструируется только один раз. В type x = x, он также конструируется один раз. Это рекомендации от основателей С++.
     
  11. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    Booster
    кстати в констукторе копий проверку на самого себя говориш не надо а std::string делает :derisive:
     
  12. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    osox
    Реализация в vs2010
    Код (Text):
    1. basic_string(const _Myt& _Right)
    2.         : _Mybase(_Right._Alval)
    3.         {    // construct by copying _Right
    4.         _Tidy();
    5.         assign(_Right, 0, npos);
    6.         }
    В assign этот случай как-то обрабатывается, но эта функция ведь и в операторе присваивания используется.
     
  13. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
  14. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    Перефразируй, пожалуйста, вопрос другими словами, не понимаю его смысл. Откуда компилятору может быть известно, что объект-источник не инициализирован? Неужели он будет проверять, не забыл ли ты реализовать в полной мере конструкторы? Говоря про глубокое копирование, я имел ввиду что тебе следует реализовать конструктор копии и оператор присваивания в соответствии с определенными требованиями.
     
  15. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    Мне кажется в данном случае следует смотреть Стандарт, и там будет неопределенное поведение.
     
  16. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    J0E
    да ладно - просто не поняли друг друга )
     
  17. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    J0E
    Вот что я там нашёл, правда в другом контексте:
    По-моему вполне определённое поведение. Правда непонятно зачем такое.