![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| marcusmae |
|
||||||
![]() stravaganza ![]() ![]() Профиль Группа: Участник Сообщений: 874 Регистрация: 26.3.2006 Репутация: 5 Всего: 39 |
Всем привет,
Сразу прошу не пугаться, если что Назову условной инициализацией следующее :
- Условное выражение в аргументе конструктора копирования класса B. А вот что может стоять на месте троеточий - аргументов? = Я так понимаю, что указатели на B. Причём такие, чтобы не возникло никаких проблем с динамическими членами. Следующий вариант не проходит :
потому что автоматический экземпляр при первой возможности удалится вместе со своими динамическими членами. Как же быть? Наверно, так :
- нормально? Это сообщение отредактировал(а) marcusmae - 1.4.2008, 14:52 -------------------- ἀπὸ μηχανῆς θεός |
||||||
|
|||||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
нет
Добавлено через 29 секунд какая сигнатура конструктора В, что он получает? Добавлено через 5 минут и 20 секунд как вариант:
но в этом случае на этапе компиляции тип конструктора должен быть известен(( |
|||
|
||||
| marcusmae |
|
|||
![]() stravaganza ![]() ![]() Профиль Группа: Участник Сообщений: 874 Регистрация: 26.3.2006 Репутация: 5 Всего: 39 |
Ну аргументы какие-то ему перепадают из конструктора A. Правильнее так :
Мне такая штука в нескольких разных местах нужна. Это сообщение отредактировал(а) marcusmae - 1.4.2008, 14:58 -------------------- ἀπὸ μηχανῆς θεός |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
||||
|
||||
| marcusmae |
|
|||
![]() stravaganza ![]() ![]() Профиль Группа: Участник Сообщений: 874 Регистрация: 26.3.2006 Репутация: 5 Всего: 39 |
Нет-нет, извините, не катит. Не перемещайте, пожалуйста, инициализацию в тело конструктора. Речь идёт именно о том, чтобы она находилась в initialization-list-е - после двоеточия. В чём конкретно состоит проблема моего варианта? Он рабочий, но очень может быть, что я не вижу какие-то подводные камни... -------------------- ἀπὸ μηχανῆς θεός |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
||||
|
||||
| marcusmae |
|
|||
![]() stravaganza ![]() ![]() Профиль Группа: Участник Сообщений: 874 Регистрация: 26.3.2006 Репутация: 5 Всего: 39 |
Да, можно копировать, но как-то излишне, по-моему. В моём фрагменте специально под экземпляр класса A для исключительного использования создаётся экземпляр B. Ну и зачем его копировать, если можно просто взять ссылку?.. Откуда? - Покажите, пожалуйста. -------------------- ἀπὸ μηχανῆς θεός |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Не получится. Разные конструкторы - разные функции, компилятор должен знать, какой конструктор подставить в момент компиляции, и динамическое значение флага ему до лампочки. Флаг может определять только конкретное значение аргумента.
Вариант ужасен и сам по себе (из-за мемори-ликов): кроме того, здесь именно и происходит вызов копирующего конструктора, которого ты так не хочешь. Причем в первой части тоже должен быть аргумент типа B&. Если бы у тебя было не наследование, а просто указатель на B, то можно было бы написать так: B (flag ? new B (...) : new B()) - т.е. использовать разные конструкторы. Если твой флаг является константой, известной в момент компиляции, то можно сделать условную инициализацию с помощью шаблона. Добавлено через 1 минуту и 11 секунд Кто разрушит указатель, созданный new? -------------------- ... |
|||
|
||||
| marcusmae |
|
|||
![]() stravaganza ![]() ![]() Профиль Группа: Участник Сообщений: 874 Регистрация: 26.3.2006 Репутация: 5 Всего: 39 |
Нет, не является. Понял, есть проблема. Конечно, либо тоже конструктор, как Вы заметили, либо какая-нибудь статическая функция, возвращающая const B&. Хорошо, допустим, я пишу копирующий конструктор, но реально копирую в нём только автоматические члены, в т.ч. указатели. Динамически выделенную память - с помощью внутренних флагов указываю, что её не должен удалять экземпляр-оригинал, но должен экземпляр-копия. Нормально? Наследование чем-то хуже?.. Это сообщение отредактировал(а) marcusmae - 1.4.2008, 16:02 -------------------- ἀπὸ μηχανῆς θεός |
|||
|
||||
| korian |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 651 Регистрация: 8.3.2008 Где: Украина, Харьков Репутация: 3 Всего: 17 |
тут два варианта, зависит от того, что из себя представляют объекты A и B. если тут действительно необходимо наследование, то надо писать копирующий конструктор. и забыть про то, что это дает "излишнее" копирование. компилятор сам сделает нужную оптимизацию. если наследование тут просто "прикручено", то убрать его и использовать указатели. Добавлено через 5 минут и 47 секунд хотя если объект B имеет не тривиальные данные, то полюбому надо описывать копирующий конструктор. или реализовывать его, или объявлять его в приват секции. Это сообщение отредактировал(а) korian - 1.4.2008, 17:22 |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Это просто пример. Кроме того, наследование действительно хуже включения, потому что образует более тесную зависимость. Но иногда действительно оно нужно. Допустим, это твой случай - нужно именно наследоваться. Вариант 1: плюнуть на доп. расходы, связанные с конструктором копировани (всякие флаги - не уничтожать указатель и прочее - ОЧЕНЬ ПЛОХОЙ ВАРИАНТ). Очень мало случаев, когда нельзя наплевать на какое-то там лишнее копирование. А преждевременная оптимизация есть ЗЛО. Вариант 2: сделать конструктор B пустым (один из) и инициализировать его в теле конструктора, написав одну или больше функций типа Сonstruct. И не надо говорить, что этого нельзя сделать - сделать можно все... почти... -------------------- ... |
|||
|
||||
| marcusmae |
|
|||
![]() stravaganza ![]() ![]() Профиль Группа: Участник Сообщений: 874 Регистрация: 26.3.2006 Репутация: 5 Всего: 39 |
Почитал, подумал, всё взвесил и понял, что раз корень зла - утечка памяти из-под new в аргументе, то почему бы не сохранить её в приватном поле? Для этого понадобилось ввести ещё один промежуточный конструктор, но не суть : как только ссылка подхвачена, её можно будет потом удалить через деструктор класса. Ну и свой конструктор копирования таки определил - тут Вы были правы
Earnest, Lazin, korian, спасибо! -------------------- ἀπὸ μηχανῆς θεός |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Вообще-то не за что. Судя по твоему посту, мы тебя не убедили - решение ты принял плохое... Ну, значит, будешь учится на своих ошибках, раз чужому опыту не веришь...
-------------------- ... |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |