Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> инициализация const в производном классе 
V
    Опции темы
ksili
  Дата 17.7.2008, 08:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



Проблема такова. Я делаю в Билдере многопоточное приложение. Для этого в нём предусмотрен класс 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 на конструкторе (на этом самом списке инициализации). Кто-нибудь знает, как можно инициализировать константные члены-данные в производном классе?

Это сообщение отредактировал(а) ksili - 17.7.2008, 09:07


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
Earnest
Дата 17.7.2008, 09:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Так много букв написал, что в этой жаре все подробно прочитать просто никак... smile 
Но если правильно поняла: константу можно инициализировать только в списке инициализации того класса, где она объявлена. А производный класс может только передать желаемый аргумент базовому. Примерно так:
Код

class Base
{
public:
   Base (int A): m_A (A) {}
private:
   const int m_A;
};

class Derived: public Base
{
public:
   Derived(): Base (5) {}
};


Это сообщение отредактировал(а) Earnest - 17.7.2008, 09:11


--------------------
...
PM   Вверх
Lazin
Дата 17.7.2008, 09:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Нужно вызывать конструктор базового класса для инициализации членов базового класса
Код


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)
        {
        }
};

PM MAIL Skype GTalk   Вверх
Earnest
Дата 17.7.2008, 09:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



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


--------------------
...
PM   Вверх
ksili
Дата 17.7.2008, 09:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



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


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
Earnest
Дата 17.7.2008, 09:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



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


--------------------
...
PM   Вверх
ksili
Дата 17.7.2008, 09:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



Цитата(Earnest @  17.7.2008,  13:15 Найти цитируемый пост)
 А константы производного класса инициализуруй на здоровье - в списке инициализации

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


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
mes
Дата 17.7.2008, 09:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(ksili @  17.7.2008,  08:41 Найти цитируемый пост)
Но из-за того, что там уже есть : 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)
    , hCom(h), this_ch(t), All_ch(a)
{
 ; // остальные действия 
}


Добавлено через 4 минуты и 21 секунду
Цитата(Earnest @  17.7.2008,  09:03 Найти цитируемый пост)
Так много букв написал, 

полностью согласен,
ksili, задавая вопрос постарайся не отходить на дополнительные описания ...трудно понять где именно проблема..  smile 

Это сообщение отредактировал(а) mes - 17.7.2008, 09:27


--------------------
PM MAIL WWW   Вверх
Ulysses4j
Дата 17.7.2008, 09:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 304
Регистрация: 6.6.2007
Где: Ростов-на-Дону

Репутация: 4
Всего: 10



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


--------------------
Communication is critical to the job of a programmer.
C. Jazdzewski. Fatherly Advice To New Programmers
PM MAIL WWW   Вверх
ksili
Дата 17.7.2008, 09:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



Цитата(mes @  17.7.2008,  13:26 Найти цитируемый пост)
вместо второго двоеточия поставь запятую :
Код

__fastcall TDispatchThread (bool CreateSuspended,HANDLE h,int t,Channels *a)
    : TThread(CreateSuspended)
    , hCom(h), this_ch(t), All_ch(a)
{
 ; // остальные действия 
}


Я так уже пробовал. При компиляции всё те же ошибки на строке 
Код

 : TThread(CreateSuspended)


Добавлено @ 09:55
Цитата(Ulysses4j @  17.7.2008,  13:44 Найти цитируемый пост)
Не может быть проблемы в несоответствии порядка объявления порядку в листе инициализации?

Я сейчас пробую с одним параметром в инициализации
Код

__fastcall TDispatchThread (bool CreateSuspended,HANDLE h)
    : TThread(CreateSuspended)
    , hCom(h)
{
 ; // остальные действия 
}

и даже вернул его назад на неконстантный, на всякий случай. Всё равно не компилируется

Это сообщение отредактировал(а) ksili - 17.7.2008, 09:56


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
mes
Дата 17.7.2008, 10:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



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



Это сообщение отредактировал(а) mes - 17.7.2008, 10:19


--------------------
PM MAIL WWW   Вверх
ksili
Дата 17.7.2008, 11:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



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 { expected
E2040 Declaration terminated incorrectly
обе ошибки на одной строке в DispatchThread.cpp:  : TThread(CreateSuspended)


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
vinter
Дата 17.7.2008, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



а попробуй написать так
Код

__fastcall TDispatchThread(bool CreateSuspended, HANDLE h) : TThread(CreateSuspended) , hCom(h)
{}

т.е в одну строку.


--------------------
Мой блог
PM MAIL WWW   Вверх
ksili
Дата 17.7.2008, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2069
Регистрация: 3.11.2005
Где: Красноярск

Репутация: 1
Всего: 17



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


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
mes
Дата 17.7.2008, 11:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



на вид все правильно у тебя, проверька на своем компиляторе этот код :
Код

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;
};




--------------------
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1286 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.