Инициализация const в производном классе

Проблема такова. Я делаю в Билдере многопоточное приложение. Для этого в нём предусмотрен класс TThread. Все потоки, создаваемые приложением должны быть потомками этого класса. У меня несколько таких потомков. Всё было нормально, пока я не захотел несколько членов этих классов сделать константными т.к. они собственно константами и являются (их значение задаётся в самом начале, и потом не меняется). Сделать это я решил, т.к. в разных местах говорится, что это гуд (см. например, С.Мэйерс "Эффективное использование С++"), но не в этом суть. Сделать-то я их сделал такими, а инициализировать не получается.Вот как они инициализировались раньше:
TDispatchThread *pdt;...pdt = new TDispatchThread (true);    // создали экземпляр класса потока и "заморозили" его                    pdt->hCom = port;    // инициализируем его членыpdt->this_ch = num - 1;pdt->All_ch = All_chnls;pdt->Resume();        // "размораживаем" поток
Конструктор, который при этом использовался, выглядит так:
__fastcall TDispatchThread(bool CreateSuspended=true)    : TThread(CreateSuspended){ this->OnTerminate = (TNotifyEvent)&OnThisTerminate; DecimalSeparator = '.'; InitializeCriticalSection(&g_cs);}
После того, как я сделал члены класса hCom, this_ch, All_ch константными, так уже делать нельзя, т.к. они инициализируются при вызове конструктора, а не после, как показано выше. Тут, насколько я понял, почитав книжки, нужно использовать конструктор со списком инициализации. Но нигде не нашёл, как это сделать именно для такого случая (конструктор производного класса). Если бы класс не был производным, его конструктор выглядел бы примерно так:
__fastcall TDispatchThread (bool CreateSuspended,HANDLE h,int t,Channels *a)    : hCom(h), this_ch(t), All_ch(a){ this->OnTerminate = (TNotifyEvent)&OnThisTerminate; DecimalSeparator = '.'; InitializeCriticalSection(&g_cs);}
 А создание объекта примерно так:
pdt = new TDispatchThread (true,port,num-1,All_chnls);
Но из-за того, что там уже есть : TThread(CreateSuspended), я не пойму куда там впихнуть список инициализации. Пробовал так:
__fastcall TDispatchThread (bool CreateSuspended,HANDLE h,int t,Channels *a)    : TThread(CreateSuspended)    : hCom(h), this_ch(t), All_ch(a)
так
__fastcall TDispatchThread (bool CreateSuspended,HANDLE h,int t,Channels *a)    : hCom(h), this_ch(t), All_ch(a)    : TThread(CreateSuspended)
так
__fastcall TDispatchThread(bool CreateSuspended, HANDLE h)    : hCom(h), this_ch(t), All_ch(a), TThread(CreateSuspended)
 и другими подобными способами. Не компилируется. Пишет ошибки { expected и Declaration terminated incorrectly на конструкторе (на этом самом списке инициализации). Кто-нибудь знает, как можно инициализировать константные члены-данные в производном классе?
14 ответов

Так много букв написал, что в этой жаре все подробно прочитать просто никак...  Но если правильно поняла: константу можно инициализировать только в списке инициализации того класса, где она объявлена. А производный класс может только передать желаемый аргумент базовому. Примерно так:
class Base{public:   Base (int A): m_A (A) {}private:   const int m_A;};class Derived: public Base{public:   Derived(): Base (5) {}};


Нужно вызывать конструктор базового класса для инициализации членов базового класса
class A{    const int a;    const int b;    public:        A(int a, int b) : a(a), b(b) {}};class B : public A{    public:        B(int a, int b) : A(a, b)        {        }};


И вообще, прямо инициализировать переменные базового класса в конструкторе производного, даже если это не константы, - плохая идея. Хорошая - сделать их приватными.


Earnest, немного не то. Константы и есть в производном классе, в секции public. Я в базовом классе ничего не меняю - он не мой.


Тогда никак. Члена-константы можно инициализировать только в списке инициализации своего конструктора.Если базовый класс не предусматривает аргументов для альтернативной инициализации своих констант, то вопросы к его автору. Возможно, есть какая-то сермяга.И если базовый класс не твой, то откуда там взялись константы, которых раньше не было? А константы производного класса инициализуруй на здоровье - в списке инициализации.


 А константы производного класса инициализуруй на здоровье - в списке инициализации
Дык, вот как раз это и не получается!    Константные члены появились в TDispatchThread, а не в TThread. Я не пойму как совместить в конструкторе производного класса указание списка инициализации hCom(h), this_ch(t), All_ch(a) и указание конструктора базового класса  TThread(CreateSuspended)


Но из-за того, что там уже есть : TThread(CreateSuspended), я не пойму куда там впихнуть список инициализации. Пробовал так:
__fastcall TDispatchThread (bool CreateSuspended,HANDLE h,int t,Channels *a)    : TThread(CreateSuspended)    : hCom(h), this_ch(t), All_ch(a)
вместо второго двоеточия поставь запятую :
__fastcall TDispatchThread (bool CreateSuspended,HANDLE h,int t,Channels *a)    : TThread(CreateSuspended)   <span> , </span>hCom(h), this_ch(t), All_ch(a){ ; // остальные действия }
Добавлено через 4 минуты и 21 секунду
Так много букв написал, 
полностью согласен,ksili, задавая вопрос постарайся не отходить на дополнительные описания ...трудно понять где именно проблема..   


Не может быть проблемы в несоответствии порядка объявления порядку в листе инициализации? В списке инициализации должны упоминаться сначала базовые классы, потом члены в порядке их объявления в классе. В случае константых членов это важно. В Новых сложных задача Саттера есть совет (14-ый), где он это подробно рассматривает.


вместо второго двоеточия поставь запятую :
__fastcall TDispatchThread (bool CreateSuspended,HANDLE h,int t,Channels *a)    : TThread(CreateSuspended)    , hCom(h), this_ch(t), All_ch(a){ ; // остальные действия }
Я так уже пробовал. При компиляции всё те же ошибки на строке 
 : TThread(CreateSuspended)
Добавлено @ 09:55
Не может быть проблемы в несоответствии порядка объявления порядку в листе инициализации?
Я сейчас пробую с одним параметром в инициализации
__fastcall TDispatchThread (bool CreateSuspended,HANDLE h)    : TThread(CreateSuspended)    , hCom(h){ ; // остальные действия }
и даже вернул его назад на неконстантный, на всякий случай. Всё равно не компилируется


ksili, покажи описание класса и код ошибки 


DispatchThread.h
class TDispatchThread : public TThread{private:protected:// тут куча функцийpublic:__fastcall TDispatchThread(bool CreateSuspended, HANDLE h);// дальше куча переменных........// одну из них хочу сделать константной /*const*/ HANDLE hCom;          // const можно и раскомментировать, ничего не изменится};
DispatchThread.cpp
__fastcall TDispatchThread(bool CreateSuspended, HANDLE h)    : TThread(CreateSuspended)    , hCom(h){ // всякие действия. h и hCom не используются}
другого конструктора нету. Класс TThread не мой - объявлен в Classes.hppВ основном процессе экземпляр моего класса TDispatchThread создается так:
pdt = new TDispatchThread(true, port);
Коды ошибок:E2275 { expectedE2040 Declaration terminated incorrectlyобе ошибки на одной строке в DispatchThread.cpp:  : TThread(CreateSuspended)


а попробуй написать так
__fastcall TDispatchThread(bool CreateSuspended, HANDLE h) : TThread(CreateSuspended) , hCom(h){}
т.е в одну строку.


vinter, ничего не изменилось


на вид все правильно у тебя, проверька на своем компиляторе этот код :
class A { public: A (int b) {} };class B : public A{    public:    B (int _i1, int _i2, int _i3) : A(_i1), i(_i2), ci(_i3) {}    int i;    const int ci;};