|
|
  |
IAR EWAVR и виртуальные функции |
|
|
|
Nov 12 2007, 12:41
|
Участник

Группа: Validating
Сообщений: 64
Регистрация: 16-06-05
Пользователь №: 6 073

|
Компилятор IAR EWAVR 4.20A Микроконтроллер ATmega128
В программе есть родительский класс и два наследованных от него класса, отличающихся парой функций. При объявлении соответствующих функций родительского класса виртуальными программа виснет где-то между __low_level_init() и main(). Если сделать функции не виртуальными, то программа работает, но вызываются функции родительского класса, а не наследованных, что делает использование наследования в данном случае бессмысленным.
В чем может быть причина полной неработоспособности программы с виртуальными функциями?
После очередной перекомпиляции еще интереснее: The application aborted Program exit reached
(отлаживаю под JTAG ICE)
Сообщение отредактировал AlexG - Nov 12 2007, 12:47
|
|
|
|
|
Nov 13 2007, 04:10
|
Участник

Группа: Validating
Сообщений: 64
Регистрация: 16-06-05
Пользователь №: 6 073

|
Разобрался. Вызывать виртуальную функцию прямо в конструкторе класса было неудачной идеей.
|
|
|
|
|
Nov 18 2007, 12:11
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(Непомнящий Евгений @ Nov 18 2007, 14:54)  А почему нельзя инициализировать его до выполнения конструктора - компилятор то уже знает, где этот указатель лежит и чему должен быть равен? Код class TSlon { ... }
...
TSlon *p = new TSlon; Где тут лежит объект и что об этом знает компилятор? То же самое и в случае с созданием автоматического объекта внутри функции. Объект в С++ конструируется только конструктором и никак иначе. Все остльные варианты реалиации - это лазейки для нетривиальных глюков.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Nov 18 2007, 12:46
|
Местный
  
Группа: Участник*
Сообщений: 418
Регистрация: 20-08-07
Пользователь №: 29 930

|
Цитата(Непомнящий Евгений @ Nov 18 2007, 11:54)  А почему нельзя инициализировать его до выполнения конструктора - компилятор то уже знает, где этот указатель лежит и чему должен быть равен? Ничего он до выполнения конструктора не знает ибо объект вообще еще не создан и ему даже память не выделена вообще до исполнения конструктора. Конструктор как раз и создает объект. В лучшем случае компилятор знает где будет лежать указатель на создаваемый объект, а указатель этот - до конструктора как правило просто пустой. И объекта еще нет...
|
|
|
|
|
Nov 18 2007, 13:17
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Я понимаю, что такой стандарт, но все ж таки как-то неудобно. Фактически получается, что любой вызов виртуальной функции в конструкторе приводит в ошибке времени выполнения. Хотя б какой-нибудь ворнинг выдавался... Цитата(dxp @ Nov 18 2007, 15:11)  Где тут лежит объект и что об этом знает компилятор? Когда вы пишите TSlon *p = new TSlon, то вначале вызывается operator new(), затем контсруктор TSlon и только затем инициализируется __vptr. Не до конца понятно, почему нельзя инициализировать __vptr до вызова конструктора - указатель на память, где будет расположен объект, уже есть.
|
|
|
|
|
Nov 18 2007, 14:58
|

Шаман
     
Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221

|
Цитата(Непомнящий Евгений @ Nov 18 2007, 15:17)  ... Когда вы пишите TSlon *p = new TSlon, то вначале вызывается operator new(), затем контсруктор TSlon и только затем инициализируется __vptr. Не до конца понятно, почему нельзя инициализировать __vptr до вызова конструктора - указатель на память, где будет расположен объект, уже есть. Ну и на что должен указывать этот указатель? На обьект, который там скоро появится? Напоминает фразу: "Вы жарьте, а рыба будет".
|
|
|
|
|
Nov 19 2007, 07:01
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Цитата(IgorKossak @ Nov 18 2007, 17:58)  Ну и на что должен указывать этот указатель? На обьект, который там скоро появится? Напоминает фразу: "Вы жарьте, а рыба будет". Указатель должен указывать на массив указателей на реализации виртуальных функции. После вызова operator new уже есть указатель на (неиниализированную) память. В этой точке также известна структура создаваемого объекта и его тип - т.е. известно, чему равен __vptr и где он находится. Почему нельзя его записать до вызова пользовательского конструктора, а не после?
|
|
|
|
|
Nov 19 2007, 07:23
|
Бывалый
    
Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615

|
Цитата(Непомнящий Евгений @ Nov 19 2007, 10:01)  Объект условно состоит из: - свойств (память типа ОЗУ); - реализаций (память типа Flash). Создание объекта подразумевает два варианта: 1. статический объект память свойств отводится уже на этапе компиляции (она строго резервируется); 2. динамическое создание объекта (память свойств отводится в куче и она находится, там где окажется).
|
|
|
|
|
Nov 19 2007, 10:24
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(Непомнящий Евгений @ Nov 19 2007, 13:01)  После вызова operator new уже есть указатель на (неиниализированную) память. В этой точке также известна структура создаваемого объекта и его тип Кому известно? Пральна - конструктору.  Цитата(Непомнящий Евгений @ Nov 19 2007, 13:01)  - т.е. известно, чему равен __vptr и где он находится. Почему нельзя его записать до вызова пользовательского конструктора, а не после? Потому, что по-вашему получается, что надо иметь два конструктора - один предварительный, для создания/инициализации vptr, второй - для всего остального. Какая такая необходимость вызвать виртуальные функции на стадии конструирования объекта?
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Nov 19 2007, 11:52
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(Непомнящий Евгений @ Nov 19 2007, 16:38)  Счас еще раз пересмотрел Страуструпа - не нашел указаний на то, что в конструкторе нельзя дергать виртуальные функции... Наверняка вы у него не найдете и того, что не надо вызывать функцию main из других функций, но это не означает, что такоей вызов надо делать?  Вопрос был о том, зачем вызывать виртуальную функцию из конструируемого объекта, в котором однозначно this содержит адрес текущего (этого конструируемого) объекта и будет вызваться совершенно понятно какая функция - т.е. никакой виртуальности тут нет, один только оверхед. Даже если проинициализировать vptr так, как вы хотите, виртуального по сути вызова тут не получится.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|