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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.85
Виктор_Сен
33 / 26 / 1
Регистрация: 01.08.2011
Сообщений: 176
#1

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

05.12.2011, 14:57. Просмотров 1743. Ответов 6
Метки нет (Все метки)

Такая проблема: имеется конструктор базового класса 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++
Привет, друзья, есть, к примеру, такие классы: class Base { public: int x; Base() { } };

Не вызывается конструктор базового класса - C++
Доброго времени суток. У меня проблема:в производном классе не вызывается конструктор базового класса. Думаю описывать класс не стоит,...

Не вызывается нужный конструктор базового класса - C++
Здравствуйте. Я пока в процессе изучения С++. Имеется следующая структура классов: Базовый: Person, расширяющие его: Student и...

Конструктор класса не видит конструктор по умолчанию другого класса - C++
Ошибка, естественно, в Classes.cpp, в строке 20. Ругается, что у класса TailNode нет конструктора по умолчанию, хотя он там, конечно, есть....

Вызов метода производного класса через обращение к методу базового класса - C++
Добрый день. Изучаю основы ООП, наткнулся на проблему. Если создавать классы внутри main.cpp, то всё нормально. Если же создавать в...

Перегрузка оператора >> для дочернего класса от базового виртуального класса - C++
Доброго вам времени суток! Программирую на С++ не давно, в связи с отсутствием должного времени на поиск ответа в глубинах учебников,...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
fasked
Эксперт С++
4934 / 2514 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
05.12.2011, 15:41 #2
Есть много вариантов решить задачу, но именно в Вашем слишком много ошибок.
Виктор_Сен
33 / 26 / 1
Регистрация: 01.08.2011
Сообщений: 176
05.12.2011, 15:43  [ТС] #3
Цитата Сообщение от fasked Посмотреть сообщение
слишком много ошибок.
Например?
fasked
Эксперт С++
4934 / 2514 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
05.12.2011, 15:56 #4
Цитата Сообщение от Виктор_Сен Посмотреть сообщение
Например?
Настолько много, что вообще непонятно чего Вы добиваетесь.
Цитата Сообщение от Виктор_Сен Посмотреть сообщение
ErrorData(ErrorCod cod
Передавать по константной ссылке, а не значению.
Цитата Сообщение от Виктор_Сен Посмотреть сообщение
При этом конструктор TimeErrorData должен принимать вместо ErrorCod только char* type и как-то передавать в конструктор базового класса структуру ErrorCod, но как это сделать?
Вызывать конструктор базового класса.
Цитата Сообщение от Виктор_Сен Посмотреть сообщение
имеется конструктор базового класса ErrorData
Где сам класс? Без него тяжело. Нужно видеть внутренности.
Kastaneda
Форумчанин
Эксперт С++
4652 / 2860 / 228
Регистрация: 12.12.2009
Сообщений: 7,268
Записей в блоге: 2
Завершенные тесты: 1
05.12.2011, 17:14 #5
Цитата Сообщение от Виктор_Сен Посмотреть сообщение
И необходимо создать дочерний класс TimeErrorData, в котором поле структуры ErrorCod.id предопределено и равно "TIME", а поле ErrorCor.type может принимать разные значения.
Можно сделать через traits'ы (в русском языке уже устоялось выражение "трэитсы")).
Вобщем вот

Добавлено через 2 минуты
что-то проблемы какие-то с ссылкой, вот http://www.cyberguru.ru/programming/cpp/cpp-traits.html
Виктор_Сен
33 / 26 / 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)
{   
}
PointsEqual
ниначмуроФ
834 / 518 / 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;
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.12.2011, 19:22
Привет! Вот еще темы с ответами:

Указатель на объект базового класса и адрес объекта производного класса - C++
Пример кода: class Class1 { public: Class1(int x) { j = new int; *j = x; } ~Class1() {delete j;}

Создание указателя типа базового класса на экземпляр производного класса - C++
Добрый день! Иногда видел коды, где создавался указатель типа базового класса на объект класса - наследника, для чего это может применяться?

Поместить в динамически расширяемый массив объекты класса, производные от базового абстрактного класса - C++
Помогите пожалуйста новичку! (мне). Я хочу создать динамически расширяющийся массив указателей на базовый абстрактный класс,...

Определить обработчик исключений на преобразование указателя базового класса на указатель производного класса - C++
Класс В является производным от класса А. Определить обработчик исключительной ситуации на преобразование указателя базового класса А на...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
05.12.2011, 19:22
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru