119 / 94 / 35
Регистрация: 18.12.2012
Сообщений: 654
|
|||||||||||||||||||||
1 | |||||||||||||||||||||
Инициализация полей класса при наследовании13.03.2017, 23:54. Показов 11539. Ответов 38
Метки нет (Все метки)
Всем добрый вечер.
Возникла у меня небольшая задачка, которую никак не могу решить. Имеем базовый класс с константным полем:
Пытаюсь сделать так :
Люди, скажите, пожалуйста, что ему не нравится ? И как можно проинициализировать константное поле в наследнике ? Спасибо.
1
|
13.03.2017, 23:54 | |
Ответы с готовыми решениями:
38
Инициализация при множественном наследовании Инициализация полей класса Инициализация полей во время объявления класса Инициализация полей класса через vector<> |
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
|
||||||
14.03.2017, 00:01 | 2 | |||||
возможно вам станет понятнее если вы в классе B создатите переменную с именем field - получается конфликт имёт по вашей логике, и field имя нельзя создавать в классе В
Ничего не смущает, что в С++ у наследников нельзя создавать имена переменных как у класса родителя?!?! А теперь по делу! Родитель создается в момент вызова конструктора А, он у вас вызывается неявно до вызова инициализации переменной field которой нету в В Таблетка:
2
|
119 / 94 / 35
Регистрация: 18.12.2012
Сообщений: 654
|
|
14.03.2017, 00:12 [ТС] | 3 |
Я и не создаю копию поля в B-классе, знаю что будет конфликт.
Тут вообще ничего не понял. Кто и когда вызывается, до какой инициализаци, почему переменной нету, если она есть, ... Сложно, конечно, это назвать "таблеткой", но как вариант - пойдёт. Спасибо. Всё равно не то, что хотелось бы...
0
|
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
|
|||||||||||
14.03.2017, 00:22 | 4 | ||||||||||
Вот еще пример
Да она есть - но она уже создана и должна была быть инициализирована! Учитывая то как вы описали вашу проблему - я с радостью всё вам объясню по 100 раз. Задайте ряд вопросов - всё разберём! Добавлено через 4 минуты
конфликт разрешаемый при явном указании к какому m_var мы обращаемся - я не зря там указал фразу "по вашей логике"
1
|
119 / 94 / 35
Регистрация: 18.12.2012
Сообщений: 654
|
|
14.03.2017, 00:24 [ТС] | 5 |
Ну, собственно, это то, что Вы раньше назвали "таблеткой". Это я уже понял...
Не понятно, почему она уже создана (ещё до создания экземпляра класса 'B'). Ведь, по сути, класса 'A', фактически не существует, и при создании экземпляра класса 'B', создаётся именно его экземпляр, в котором существуют все переменные, находящиеся в 'A'. Грубо говоря, просто копируются. Тогда не понятно, почему её нет в 'B'.
0
|
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
|
|
14.03.2017, 00:28 | 6 |
Пример с MustBeInited() - он вызывается до SomeVar( int f )
Это не верно. Фактическим называется то, что можно потрогать. Вам привести пример где можно обращаться к полям родителя или его методам? Он есть - но поглащён классом Б как наследник. Тоже не верно. При "грубом копировании" не вызывался бы конструктор родителя как полноценного объекта. Класс А есть в классе Б - можно ведь обратиться к полям на чтение и запись!
1
|
119 / 94 / 35
Регистрация: 18.12.2012
Сообщений: 654
|
||||||
14.03.2017, 00:53 [ТС] | 7 | |||||
Мда... Я начинаю понимать, что и ничего не понимаю...
Попробую описать общую задачу. Имеем базовый класс. У него есть свой конструктор. Он вызывается раньше всех производных конструкторов - в этом, как раз у меня и проблема. Мне необходимо, создавая наследника, проинициализировать переменную раньше, чем вызовется конструктор базового класса. Для примера :
0
|
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
|
||||||
14.03.2017, 00:59 | 8 | |||||
Может меня попровят сторожили, но это невозможно
Если рассуждать от обратного, то наследник, по вашей логике, инициализирует поле родителя. А если он этого не сделает? Она будет в подвешенном состоянии? Ну вот забыл родитель это сделать .... . После вызова конструтора родителя объект, что внутри родителя должен уже быть в полной боевой готовности!
0
|
119 / 94 / 35
Регистрация: 18.12.2012
Сообщений: 654
|
||||||
14.03.2017, 01:03 [ТС] | 9 | |||||
На этот случай в родителе дефолтное значение :
Как раз, таки, мне это и нужно. Если в наследнике не указать значение, то оно будет неким по-умолчанию. Это один из моментов в моей задаче.
0
|
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
|
||||||
14.03.2017, 01:12 | 10 | |||||
Просто приймите за факт фразу далее: эта запись сахарок записи
Добавлено через 3 минуты alkl, нельзя в списки инициализации наследника инициализировать поля родителя, потому что они уже проинициализированы - смотрите еще раз пример с MustBeInited() Добавлено через 4 минуты Еще довод: http://en.cppreference.com/w/c... lizer_list and non-static subobjects data members ? Нету такой - потому, что это не верно
1
|
119 / 94 / 35
Регистрация: 18.12.2012
Сообщений: 654
|
|
14.03.2017, 01:13 [ТС] | 11 |
Странно, что компиль ругается на то, что поля не существует. Скорее, его просто ещё нет до создании экземпляра, и добавляется оно только когда он создаётся.
Будем дальше думать, спасибо...
0
|
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
|
|
14.03.2017, 01:15 | 12 |
Да есть оно там! Я уже начинаю повторяться))))))) Он ругается, потому что думает что вы забыли создать в Б поле field, а уже стремитесь его проинитить - он же не может писать ошибку :
Cannot init base class member - он не подозревает, что вы хотите невозможного
1
|
119 / 94 / 35
Регистрация: 18.12.2012
Сообщений: 654
|
|
14.03.2017, 01:23 [ТС] | 13 |
Ну и я о том. Он в этот момент его не видит и думает, что я забыл его добавить. А после его создания, уже видны все поля родителя, по этому я в его конструкторе спокойно могу обращаться к любому полю родителя.
Извините, не хотел заставлять Вас это делать В общем, картина стала ясна. Будем кумекать, как лучше сделать ... Хочется иметь некоторые переменные по-умолчанию, а при создании наследника, иметь возможность их изменять до вызова базового конструктора. Причём, хотелось бы это делать в виде списка инициализации.
0
|
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
|
||||||
14.03.2017, 01:25 | 14 | |||||
_q(18) описал в посте после фразы Еще довод: . Он не верит своим двоичным сердцем, что вы настолько ошибаетесь, что пытаесь проинить то, что не можете - что можно проинить описано по ссылке http://en.cppreference.com/w/c... lizer_list
1
|
119 / 94 / 35
Регистрация: 18.12.2012
Сообщений: 654
|
|||||||||||
14.03.2017, 01:35 [ТС] | 15 | ||||||||||
Значит, по мнению компилятора, в случае
Картина ещё интереснее разворачивается
0
|
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
|
|
14.03.2017, 01:46 | 16 |
alkl, ага - почитайте ошибки
http://rextester.com/ITI45792 _q(18) http://rextester.com/KAGWC31525 _t(_q)
0
|
Игогошка!
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
|
|
14.03.2017, 01:46 | 17 |
Говорят, что какая-то разница все-таки есть.
https://github.com/isocpp/CppC... rs-instead
1
|
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
|
|
14.03.2017, 01:50 | 18 |
ct0r,
Но моё мнение, полный бред. Особенно, при good practice мы упираемся рогами в Foo{"Hello", 12}
0
|
119 / 94 / 35
Регистрация: 18.12.2012
Сообщений: 654
|
|
14.03.2017, 01:56 [ТС] | 19 |
_q забыли просто вписать в класс 'A'. С ней нет никаких ошибок, и _q нормально видится в списке инициализации. Но только для чтения.
http://rextester.com/KXUTNA47635
0
|
Игогошка!
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
|
|
14.03.2017, 01:58 | 20 |
0
|
14.03.2017, 01:58 | |
14.03.2017, 01:58 | |
Помогаю со студенческими работами здесь
20
Инициализация вещественных статических константных полей класса С++ Инициализация полей структуры в конструкторе по-умолчанию класса Ошибка при наследовании класса Ошибки при наследовании класса Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |