Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
Антон219
0 / 0 / 0
Регистрация: 09.06.2013
Сообщений: 72
#1

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

27.06.2014, 04:01. Просмотров 791. Ответов 18
Метки нет (Все метки)

Привет, друзья, есть, к примеру, такие классы:

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 Base
{
public:
    int x;
    Base()
    {
    }
};
 
class inheritor1 : public Base
{
    inheritor1()
    {
        x=1;
        function1(x);
        function2(x);
        ...
        functionN(x);
    }
};
 
class inheritor2 : public Base
{
    inheritor2()
    {
        x=2;
        function(x);
        function2(x);
        ...
        functionN(x);
    }
};
все функции (function) определены в базовом классе, их очень много, поэтому не хочется прописывать все их вызовы во всех конструкторах дочерних классов, но также нельзя перенести их и в конструктор базового класса, т. к. они могут быть вызваны только после инициализации переменной X, а в каждом дочернем классе она разная. Что можете посоветовать? можно ли сделать так, чтобы только в одном месте нужно было вызывать все эти функции
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.06.2014, 04:01
Ответы с готовыми решениями:

Вызвать конструктор производного класса без конструктора базового класса
Здравствуйте! У меня есть базовый класс треугольник и производный класс...

Конструктор базового класса
Такая проблема: имеется конструктор базового класса ErrorDataErrorData(ErrorCod...

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

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

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

18
DrOffset
7996 / 4637 / 1127
Регистрация: 30.01.2014
Сообщений: 7,543
27.06.2014, 04:08 #2
Лучший ответ Сообщение было отмечено Антон219 как решение

Решение

Цитата Сообщение от Антон219 Посмотреть сообщение
а в каждом дочернем классе она разная.
Почему бы не передавать ее параметром конструктора базового класса. Пытаться "инициализировать"* переменную базового класса из наследника напрямую - плохая идея.
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
class Base
{
public:
    int x;
    Base(int x) : x(x)
    {
        function1(x);
        function2(x);
        ...
        functionN(x);
    }
};
 
class inheritor1 : public Base
{
    inheritor1() : Base(1)
    {
    }
};
 
class inheritor2 : public Base
{
    inheritor2() : Base(2)
    {
    }
};
1
Avazart
Эксперт С++
7718 / 5627 / 549
Регистрация: 10.12.2010
Сообщений: 25,333
Записей в блоге: 17
27.06.2014, 04:20 #3
Цитата Сообщение от Антон219 Посмотреть сообщение
public: int x;
Уже тут ошибка, открытых членов класса не должно быть, это плохой тон.
1
Ilot
Эксперт С++
1831 / 1189 / 342
Регистрация: 16.05.2013
Сообщений: 3,139
Записей в блоге: 5
Завершенные тесты: 1
27.06.2014, 08:40 #4
Может стоит использовать функцию обертку для вызова всех ваших функций?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Base {
    int x;
public:
    Base(int X): x(X)
    {}
    ...
    function_wrapper(int X) {
        function1(X);
        function2(X);
        ...
        functionN(X);    
    }
};
 
class inheritor1 : public Base  {
public:
    inheritor1(int X): Base(X)
    {}
    function_wrapper(x);
};
1
Tulosba
:)
Эксперт С++
4747 / 3241 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
27.06.2014, 10:07 #5
Цитата Сообщение от Avazart Посмотреть сообщение
Уже тут ошибка, открытых членов класса не должно быть, это плохой тон.
Я думаю, это всего лишь пример, демонстрирующий принадлежность переменной x именно базовому классу. Потому как и функций с именами function1...N быть не должно
Ilot, всё же function_wrapper() имеет смысл сделать protected. Или даже private, если ее вызов может быть перенесен в конструктор Base, как предлагает DrOffset.

Не по теме:

Ilot, и добавлю немного занудства. Надеюсь Вы в реальном коде не используете одновременно переменные с одинаковым именем, но в разных регистрах.

2
Ilot
Эксперт С++
1831 / 1189 / 342
Регистрация: 16.05.2013
Сообщений: 3,139
Записей в блоге: 5
Завершенные тесты: 1
27.06.2014, 10:23 #6
Цитата Сообщение от Tulosba Посмотреть сообщение
Ilot, всё же function_wrapper() имеет смысл сделать protected.
Ну да имелось ввиду как protected. Она же для внутреннего пользования
Добавление функции обертки позволит вызывать данные функции не только при конструировании объекта, но и, например, в присвоении, хотя в этом случае и спецификатор для переменной необходимо менять на protected.
1
Avazart
Эксперт С++
7718 / 5627 / 549
Регистрация: 10.12.2010
Сообщений: 25,333
Записей в блоге: 17
27.06.2014, 12:47 #7
В DrOffset примере ф-ции вызываться уже в базовом классе хотя их там нет.
1
Tulosba
:)
Эксперт С++
4747 / 3241 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
27.06.2014, 12:53 #8
Цитата Сообщение от Avazart Посмотреть сообщение
В DrOffset примере ф-ции вызываться уже в базовом классе хотя их там нет.
Но это ведь не значит, что так не должно получиться в итоге Если некоторые действия характерны для всех наследников очевидно перенести их в базовый класс.
1
DrOffset
7996 / 4637 / 1127
Регистрация: 30.01.2014
Сообщений: 7,543
27.06.2014, 16:04 #9
Цитата Сообщение от Avazart Посмотреть сообщение
В DrOffset примере ф-ции вызываться уже в базовом классе хотя их там нет.
Потому что DrOffset прочитал что хочет ТС. Вот же написано в стартовом сообщени:
Цитата Сообщение от Антон219 Посмотреть сообщение
все функции (function) определены в базовом классе, их очень много,
1
Антон219
0 / 0 / 0
Регистрация: 09.06.2013
Сообщений: 72
29.06.2014, 04:51  [ТС] #10
Да, ребят, функции действительно в базовом классе определены, я забыл это вам прописать, надо было хоть многоточие поставить. DrOffset, да, что-то я не подумал об этом, наверное опыта мало, спасибо!. Ilot, к своему стыду, никогда не слышал о функциях обертки, попробую сделать и так тоже, чтоб разобраться в них, спасибо за пример! Вообще, всем спасибо, что помогаете!))

Добавлено через 30 минут
DrOffset, ты писал:
Цитата Сообщение от DrOffset Посмотреть сообщение
Пытаться "инициализировать"* переменную базового класса из наследника напрямую - плохая идея.
Ты имеешь ввиду, что если переменная объявлена в базовом классе, ее надо инициализировать в конструкторе базового же класса, а в наследных - вызывать конструктор базового в списке инициализации? Это применимо ко всем переменным базовых классов, я имею ввиду - это правила хорошего тона?
0
Renji
2102 / 1543 / 470
Регистрация: 05.06.2014
Сообщений: 4,473
29.06.2014, 05:02 #11
Это применимо ко всем переменным базовых классов, я имею ввиду - это правила хорошего тона?
Это банально удобнее. Может завтра захочется эту переменную const сделать. А тут опаньки, const можно только через список инициализации инициализировать.
1
Антон219
0 / 0 / 0
Регистрация: 09.06.2013
Сообщений: 72
29.06.2014, 05:27  [ТС] #12
Понял, Renji, я этого не знал, спасибо
0
DrOffset
7996 / 4637 / 1127
Регистрация: 30.01.2014
Сообщений: 7,543
29.06.2014, 05:33 #13
Цитата Сообщение от Антон219 Посмотреть сообщение
Это применимо ко всем переменным базовых классов, я имею ввиду - это правила хорошего тона?
Это и правило хорошего тона. И следствие механики языка. Инициализировать переменные базового класса можно только из конструктора базового класса. То что было у тебя - это присваивание. А инициализации вследствие отсутствия ее в конструкторе вообще не было. Поэтому я ее в том посте в кавычках написал.
1
Avazart
Эксперт С++
7718 / 5627 / 549
Регистрация: 10.12.2010
Сообщений: 25,333
Записей в блоге: 17
29.06.2014, 14:33 #14
Цитата Сообщение от Tulosba Посмотреть сообщение
Я думаю, это всего лишь пример, демонстрирующий принадлежность переменной x именно базовому классу. Потому как и функций с именами function1...N быть не должно
Оно то пример, но если переменную сделать закрытой, то классы наследники ничего о ней не могу знать, а значит инициализация должна лежать на базовом классе, а не классе наследнике.
1
Антон219
0 / 0 / 0
Регистрация: 09.06.2013
Сообщений: 72
29.06.2014, 21:03  [ТС] #15
Спасибо, ребят! Теперь так буду делать
0
Антон219
0 / 0 / 0
Регистрация: 09.06.2013
Сообщений: 72
01.07.2014, 19:34  [ТС] #16
Ребят, скажите, а если такой вариант: да, я вызываю все функции в базовом конструкторе, перед этим инициализируя i в списке инициализации (вызываю конструктор базового в дочернем), но если у меня у наследника1 есть два своих наследника, то я уже не могу в них вызывать конструктор базового(самого первого) класса? Как тогда быть? Множественное наследование? Его вроде не советуют
0
Renji
2102 / 1543 / 470
Регистрация: 05.06.2014
Сообщений: 4,473
01.07.2014, 19:44 #17
но если у меня у наследника1 есть два своих наследника, то я уже не могу в них вызывать конструктор базового(самого первого) класса? Как тогда быть?
Передавать аргументы по цепочке. Конструктор класса А передает аргумент конструктору предку Б, конструктор предка Б передает аргумент своему предку В, и так пока аргумент не доберется куда надо.
1
DrOffset
7996 / 4637 / 1127
Регистрация: 30.01.2014
Сообщений: 7,543
01.07.2014, 19:56 #18
Антон219,
1. Параметры самых базовых протащить в промежуточный класс
2. сделать так:
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
class Base
{
public:
    Base(int a, int b) : a(a), b(b) {}
    Base(Base const & x) : a(x.a), b(x.b) {}
private:
    int a, b;
};
 
class Derived1 : public Base
{
public:
    Derived1(int a, int b, int c) : Base(a, b), c(c) {} //1
    Derived1(Base const & x, int c) : Base(x), c(c) {}  //2
private:
    int c;    
};
 
class Derived2 : public Derived1
{
public:
    Derived2() : Derived1(1, 2, 3) {} //1
    Derived2() : Derived1(Base(1, 2), 3) {} //2
};
1
Антон219
0 / 0 / 0
Регистрация: 09.06.2013
Сообщений: 72
02.07.2014, 01:15  [ТС] #19
Да, разобрался, спасибо
0
02.07.2014, 01:15
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.07.2014, 01:15

Почему объект производного класса не видит префиксный оператор из базового класса?
Короче создал я базовый класс с перегруженным префиксным оператором ++. Потом...

Как сложить объект базового класса с объектом производного(наследуемого класса)
Как умножить объект базового класса с объектом производного(наследуемого...

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


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

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Опции темы

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