Форум программистов, компьютерный форум CyberForum.ru

Конструктор базового класса - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.85
Виктор_Сен
 Аватар для Виктор_Сен
29 / 22 / 1
Регистрация: 01.08.2011
Сообщений: 176
05.12.2011, 14:57     Конструктор базового класса #1
Такая проблема: имеется конструктор базового класса ErrorData
C++
1
ErrorData(ErrorCod cod, bool isFatal);
, где ErrorCod вот такая стуктура:
C++
1
2
3
4
5
    struct ErrorCod
    {
        char* id;
        char* type;
    };
И необходимо создать дочерний класс TimeErrorData, в котором поле структуры ErrorCod.id предопределено и равно "TIME", а поле ErrorCor.type может принимать разные значения. При этом конструктор TimeErrorData должен принимать вместо ErrorCod только char* type и как-то передавать в конструктор базового класса структуру ErrorCod, но как это сделать? Пробовал писать вот так:
C++
1
TimeErrorData::TimeErrorData(char* type, bool isFatal):ErrorData({"TIME",type},isFatal)
но компилятор пишет что такая конструкция неправильна. Если не указывать явно конструктор базового класса, то колмпилятор пишет что нет подходящего конструктора по умолчанию. Так как вызвать конструктор базового класса с произвольными параметрами, которых нет в конструкторе-потомке?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.12.2011, 14:57     Конструктор базового класса
Посмотрите здесь:

C++ Не вызывается конструктор базового класса
Не вызывается нужный конструктор базового класса C++
C++ Использование перегруженного оператора ввода/вывода в поток базового класса для объекта производного класса
Вызов метода базового класса из класса-потомка C++
C++ Как построить экземпляр дочернего класса на основе готового экземпляра базового класса?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
fasked
Эксперт C++
 Аватар для fasked
4924 / 2504 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
05.12.2011, 15:41     Конструктор базового класса #2
Есть много вариантов решить задачу, но именно в Вашем слишком много ошибок.
Виктор_Сен
 Аватар для Виктор_Сен
29 / 22 / 1
Регистрация: 01.08.2011
Сообщений: 176
05.12.2011, 15:43  [ТС]     Конструктор базового класса #3
Цитата Сообщение от fasked Посмотреть сообщение
слишком много ошибок.
Например?
fasked
Эксперт C++
 Аватар для fasked
4924 / 2504 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
05.12.2011, 15:56     Конструктор базового класса #4
Цитата Сообщение от Виктор_Сен Посмотреть сообщение
Например?
Настолько много, что вообще непонятно чего Вы добиваетесь.
Цитата Сообщение от Виктор_Сен Посмотреть сообщение
ErrorData(ErrorCod cod
Передавать по константной ссылке, а не значению.
Цитата Сообщение от Виктор_Сен Посмотреть сообщение
При этом конструктор TimeErrorData должен принимать вместо ErrorCod только char* type и как-то передавать в конструктор базового класса структуру ErrorCod, но как это сделать?
Вызывать конструктор базового класса.
Цитата Сообщение от Виктор_Сен Посмотреть сообщение
имеется конструктор базового класса ErrorData
Где сам класс? Без него тяжело. Нужно видеть внутренности.
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4236 / 2769 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
05.12.2011, 17:14     Конструктор базового класса #5
Цитата Сообщение от Виктор_Сен Посмотреть сообщение
И необходимо создать дочерний класс TimeErrorData, в котором поле структуры ErrorCod.id предопределено и равно "TIME", а поле ErrorCor.type может принимать разные значения.
Можно сделать через traits'ы (в русском языке уже устоялось выражение "трэитсы")).
Вобщем вот

Добавлено через 2 минуты
что-то проблемы какие-то с ссылкой, вот http://www.cyberguru.ru/programming/cpp/cpp-traits.html
Виктор_Сен
 Аватар для Виктор_Сен
29 / 22 / 1
Регистрация: 01.08.2011
Сообщений: 176
05.12.2011, 18:20  [ТС]     Конструктор базового класса #6
Цитата Сообщение от fasked Посмотреть сообщение
Передавать по константной ссылке, а не значению.
А что это даёт? Я же не всю строку передаю, а только два указателя: id и type, завёрнутые в структуру. Если передавать по константной ссылке, то будет передаваться 1 указатель (замаскированный под ссылку). Я думал это не существенно.

Цитата Сообщение от fasked Посмотреть сообщение
Вызывать конструктор базового класса.
Ну это понятно, но пробема в том, что конструктор базового класса вызывается всегда до вызова конструктора дочернего, а если нужно сделать некоторые вычисления и в зависимости от их результатов вызывать конструктор базового класса с разными параметрами или даже разные перегруженные конструкторы, но при записи типа "DerivedConstructor(bla-bla-bla):ParentConstructor(bla-bla) {}" я не имею возможности производить вычисления до вызова базового конструктора. Например в Delphi базовый конструктор не вызывается сразу, а явно в конструкторе дочернего класса с использованием ключевого слова "inherited", котя конечно это может вызывать ошибки связанные с тем, что конструктор базового класса может быть не вызван вообще. Но в принципе проблема решается тем, что можно определить конструктор базового класса без параметров (как некоторая временная "заглушка"), который будет устанавливать некоторый флаг внутри объекта, что объект ещё не готов к использованию, и потом явно вызывать конструктор базового класса с уже вычисленными параметрами, но это не очень красиво.

Цитата Сообщение от fasked Посмотреть сообщение
Где сам класс?
Вот он:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//Передаётся по указателю функции обработки ошибки, 
//если в главном модуле задан адрес такой функции,
//а если нет, то генерируется исключение с типом этого класса
class ErrorData
{
 
public:
 
    struct ErrorCod
    {
        char* id;
        char* type;
    };
 
private:
 
    ErrorCod errorCod;//Код ошибки
    u1 counter;//Счётчик ошибок
    bool isFatalError;//Флаг фатальности ошибки
 
public:
    
    ErrorData(ErrorCod cod, bool isFatal);
    virtual ~ErrorData();
    virtual wchar_t* getDescription()=0;//Выдаёт описание ошибки
    void incCounter();//Увеличивает счётчик числа ошибок, если они повторяются
    u1 getCounter();//Получение значения счётчика
    ErrorCod getCod();//Считывание кода ошибки
    bool getIsFatal();//Фатальна ли ошибка
    void setIsFatal(bool isFatal);//Задание фатальности ошибки
    
};
примечание: u1 значит тип unsigned длиной 1 байт
Вот конструктор:
C++
1
2
3
4
5
6
ErrorData::ErrorData(ErrorCod cod, bool isFatal)
{
    counter=0;
    errorCod=cod;
    isFatalError=isFatal;
}
Вот один из дочерних класов:
C++
1
2
3
4
5
6
7
8
9
10
11
//id=TIME
class TimeErrorData: public ErrorData
{
 
public:
 
    virtual wchar_t* getDescription();
    TimeErrorData(char* type, bool isFatal);
    virtual ~TimeErrorData();
 
};
Вот его конструктор, который ни чего не делает, только передаёт конструктору базового класса параметры:
C++
1
2
3
4
//Ошибка!!!
TimeErrorData::TimeErrorData(char* type, bool isFatal):ErrorData({"TIME",type},isFatal)
{   
}
Цитата Сообщение от fasked Посмотреть сообщение
вообще непонятно чего Вы добиваетесь
Вот в принцие и всё, чего я добиваюсь. Хотя код будет рабочий если код ошибки держать не в одной структуре, а разбить на составляющие, тогда конструктор ErrorData будет уже получать два указателя а конструктор TimeErrorData только один и передавать в ErrorData "TIME" и свой указатель. Тогда получится вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//Передаётся по указателю функции обработки ошибки, 
//если в главном модуле задан адрес такой функции,
//а если нет, то генерируется исключение с типом этого класса
class ErrorData
{
 
private:
 
    char* errorId;//Класс ошибки
    char* errorType;//Конкретный тип ошибки
    u1 counter;//Счётчик ошибок
    bool isFatalError;//Флаг фатальности ошибки
 
public:
    
    ErrorData(char* id, char* type, bool isFatal);
    virtual ~ErrorData();
    virtual wchar_t* getDescription()=0;//Выдаёт описание ошибки
    void incCounter();//Увеличивает счётчик числа ошибок, если они повторяются
    u1 getCounter();//Получение значения счётчика
    char* getId();//Считывание id ошибки
    char* getType();//Считывание типа ошибки
    bool getIsFatal();//Фатальна ли ошибка
    void setIsFatal(bool isFatal);//Задание фатальности ошибки
    
};
 
//id=TIME
class TimeErrorData: public ErrorData
{
 
public:
 
    virtual wchar_t* getDescription();
    TimeErrorData(char* type, bool isFatal);
    virtual ~TimeErrorData();
 
};
 
ErrorData::ErrorData(char* id, char* type, bool isFatal)
{
    counter=0;
    errorId=id;
    errorType=type;
    isFatalError=isFatal;
}
 
TimeErrorData::TimeErrorData(char* type, bool isFatal):ErrorData("TIME",type,isFatal)
{   
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.12.2011, 19:22     Конструктор базового класса
Еще ссылки по теме:

C++ Создать массив указателей базового класса и присвоить ему адреса каждого из екземпляров класса
Конструктор базового класса C++
Указатель на объект базового класса и адрес объекта производного класса C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
PointsEqual
ниначмуроФ
 Аватар для PointsEqual
832 / 516 / 33
Регистрация: 12.10.2009
Сообщений: 1,915
05.12.2011, 19:22     Конструктор базового класса #7
Виктор_Сен, не знаю для чего используются ваши классы, но вот так работает:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
 
using namespace std;
 
class ErrorData
{
public:
    struct ErrorCod;
 
    ErrorData(ErrorCod cod, bool isFatal)
        :errorCod(cod),
         isFatalError(isFatal)
    {
    }
 
        struct ErrorCod
        {
                char* id;
                char* type;
        };
private:
        ErrorCod errorCod;//Код ошибки
        bool isFatalError;//Флаг фатальности ошибки
};
 
 
class TimeErrorData: public ErrorData
{
public:
    TimeErrorData(char* type, bool isFatal)
        :ErrorData({"TIME",type},isFatal)
    {
    }
 
private:
 
};
 
 
int main()
{
    TimeErrorData td("123", true);
    
    return 0;
}
Yandex
Объявления
05.12.2011, 19:22     Конструктор базового класса
Ответ Создать тему
Опции темы

Текущее время: 10:24. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru