| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > инициализация const в производном классе |
| Автор: ksili 17.7.2008, 08:41 | ||||||||||||||
| Проблема такова. Я делаю в Билдере многопоточное приложение. Для этого в нём предусмотрен класс TThread. Все потоки, создаваемые приложением должны быть потомками этого класса. У меня несколько таких потомков. Всё было нормально, пока я не захотел несколько членов этих классов сделать константными т.к. они собственно константами и являются (их значение задаётся в самом начале, и потом не меняется). Сделать это я решил, т.к. в разных местах говорится, что это гуд (см. например, С.Мэйерс "Эффективное использование С++"), но не в этом суть. Сделать-то я их сделал такими, а инициализировать не получается. Вот как они инициализировались раньше:
Конструктор, который при этом использовался, выглядит так:
После того, как я сделал члены класса hCom, this_ch, All_ch константными, так уже делать нельзя, т.к. они инициализируются при вызове конструктора, а не после, как показано выше. Тут, насколько я понял, почитав книжки, нужно использовать конструктор со списком инициализации. Но нигде не нашёл, как это сделать именно для такого случая (конструктор производного класса). Если бы класс не был производным, его конструктор выглядел бы примерно так:
А создание объекта примерно так:
Но из-за того, что там уже есть : TThread(CreateSuspended), я не пойму куда там впихнуть список инициализации. Пробовал так:
так
так
и другими подобными способами. Не компилируется. Пишет ошибки { expected и Declaration terminated incorrectly на конструкторе (на этом самом списке инициализации). Кто-нибудь знает, как можно инициализировать константные члены-данные в производном классе? |
| Автор: Earnest 17.7.2008, 09:03 | ||
| Так много букв написал, что в этой жаре все подробно прочитать просто никак... Но если правильно поняла: константу можно инициализировать только в списке инициализации того класса, где она объявлена. А производный класс может только передать желаемый аргумент базовому. Примерно так:
|
| Автор: Lazin 17.7.2008, 09:04 | ||
Нужно вызывать конструктор базового класса для инициализации членов базового класса
|
| Автор: Earnest 17.7.2008, 09:05 |
| И вообще, прямо инициализировать переменные базового класса в конструкторе производного, даже если это не константы, - плохая идея. Хорошая - сделать их приватными. |
| Автор: ksili 17.7.2008, 09:06 |
| Earnest, немного не то. Константы и есть в производном классе, в секции public. Я в базовом классе ничего не меняю - он не мой. |
| Автор: Earnest 17.7.2008, 09:15 |
| Тогда никак. Члена-константы можно инициализировать только в списке инициализации своего конструктора. Если базовый класс не предусматривает аргументов для альтернативной инициализации своих констант, то вопросы к его автору. Возможно, есть какая-то сермяга. И если базовый класс не твой, то откуда там взялись константы, которых раньше не было? А константы производного класса инициализуруй на здоровье - в списке инициализации. |
| Автор: mes 17.7.2008, 09:26 | ||||||
вместо второго двоеточия поставь запятую :
Добавлено через 4 минуты и 21 секунду полностью согласен, ksili, задавая вопрос постарайся не отходить на дополнительные описания ...трудно понять где именно проблема.. |
| Автор: Ulysses4j 17.7.2008, 09:44 |
| Не может быть проблемы в несоответствии порядка объявления порядку в листе инициализации? В списке инициализации должны упоминаться сначала базовые классы, потом члены в порядке их объявления в классе. В случае константых членов это важно. В Новых сложных задача Саттера есть совет (14-ый), где он это подробно рассматривает. |
| Автор: ksili 17.7.2008, 09:52 | ||||||||||
Я так уже пробовал. При компиляции всё те же ошибки на строке
Добавлено @ 09:55
Я сейчас пробую с одним параметром в инициализации
и даже вернул его назад на неконстантный, на всякий случай. Всё равно не компилируется |
| Автор: mes 17.7.2008, 10:18 |
| ksili, покажи описание класса и код ошибки |
| Автор: ksili 17.7.2008, 11:37 | ||||||
DispatchThread.h
DispatchThread.cpp
другого конструктора нету. Класс TThread не мой - объявлен в Classes.hpp В основном процессе экземпляр моего класса TDispatchThread создается так:
Коды ошибок: E2275 { expected E2040 Declaration terminated incorrectly обе ошибки на одной строке в DispatchThread.cpp: : TThread(CreateSuspended) |
| Автор: vinter 17.7.2008, 11:48 | ||
а попробуй написать так
т.е в одну строку. |
| Автор: ksili 17.7.2008, 11:53 |
| vinter, ничего не изменилось |
| Автор: mes 17.7.2008, 11:55 | ||
на вид все правильно у тебя, проверька на своем компиляторе этот код :
|
| Автор: Lazin 17.7.2008, 12:10 | ||
попробуй
|
| Автор: UnrealMan 17.7.2008, 12:19 | ||
Кроме читабельности от порядка инициализаторов в списке инициализации не зависит ровным счётом ничего. И константность в этом плане ни на что не влияет. |
| Автор: ksili 17.7.2008, 12:26 | ||||
Проверил: как консольное скомпилировалось без проблем, а как VCL - скомпилировалось, но при запуске происходит исключение в конструкторе формы Lazin, попробовал - не помогло |
| Автор: mes 17.7.2008, 12:35 | ||||
при несоблюдении порядка в списке инициализации мой компилятор начинает кричать о несправедливости )) что то я запутался, а с таким коструктором компилится ? :
|
| Автор: UnrealMan 17.7.2008, 12:42 | ||
В виде предупреждений или ошибок? |
| Автор: mes 17.7.2008, 12:46 |
предупреждение |
| Автор: UnrealMan 17.7.2008, 12:50 |
Ну, тем самым компилятор намекает на плохую читабельность |
| Автор: Ulysses4j 17.7.2008, 12:57 | ||
Да, ошибся: сложности возникают, если есть зависимости между инициализацией разных членов класса. В списке инициализировали один член, потом с его помощью второй, но если в реальности они будут инициализироваться в обратном порядке (если объявлены в другом), то будут проблемы. |
| Автор: ksili 17.7.2008, 12:58 | ||
А-а-а!!! вот я идиот! Забыл вот это: TDispatchThread::
Теперя всё компилится |
| Автор: mes 17.7.2008, 13:03 |
приятно слышать, что разобрался со своей проблемой |