![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| valex13 |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 29.1.2003 Где: Иркук. область, г . Иркутск Репутация: нет Всего: 1 |
Господа! Как сделать линейку объектов конструкторы бы которых запускались не с низу в верх ( от предка к потомкам ), а наоборот. Например если делать виртуальный метод, то происходит именно так.
|
|||
|
||||
| RAN |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 709 Регистрация: 14.3.2003 Где: Щёлково Моск.обл. Репутация: 5 Всего: 6 |
Я чего-то не понял, что это значит. А по поводу конструкторов, мне вот что интересно: нельзя ли явно вызывать конструктор предка в конструторе потомка (сам не пробывал, компилятора под рукой нет)
|
||||
|
|||||
| vickr |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 183 Регистрация: 13.5.2003 Где: Санкт-Петербург Репутация: нет Всего: нет |
To RAN
Да, но более привычный синтаксис (по крайней мере, именно так - можно):
--------------------
Каждую секунду, тыкая в клавиши, мы давим насмерть не менее 1000 микробов =:) |
|||
|
||||
| RAN |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 709 Регистрация: 14.3.2003 Где: Щёлково Моск.обл. Репутация: 5 Всего: 6 |
vickr, по-моему ты не понял. Твой синтаксис запустит сначала конструктор A, а затем B. Надо то наоборот. Как?
|
|||
|
||||
| Vyacheslav |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2124 Регистрация: 25.3.2002 Где: Москва Репутация: 9 Всего: 59 |
В С++ виртуальных конструкторов не существует. Так же нельзя поменять порядок вызова конструкторов предков. Это данность языка и с этим ничего поделать нельзя. Исключением их правила являются виртуальные конструкторы VCL-библиотеки, но "тяжкое наследие" Object Pascal.
Что же касается самой необходимости его применения, скажи что ты хочешь и я скажу (может быть) что делать. Да, и еще одно: виртуальные методы предназначены не для изменения порядка вызова, а для поддержки полиморфизма. -------------------- С уважением, Вячеслав Ермолаев |
|||
|
||||
| valex13 |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 29.1.2003 Где: Иркук. область, г . Иркутск Репутация: нет Всего: 1 |
Я использую их пока для изменения порядка вызова. Например метод GetData для нового обьекта ( потомка ) будет вперед запущен, а потом ( если я укажу в методе ) вызову метод предка.
У меня в конструкторе предка стоит загрузка конкретной DLL и вся работа завязана на ее "хендле". Получается если я создам новый обьект и мне зохочеться указать название DLL другое, то облом? Не хочеться мне заводить еще одну загрузку DLL (Динамическую). А если даже и загрузить, то тогда что делать со старой? |
|||
|
||||
| DENNN |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3878 Регистрация: 27.3.2002 Где: Москва Репутация: 1 Всего: 43 |
если оформить так?
|
|||
|
||||
| valex13 |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 29.1.2003 Где: Иркук. область, г . Иркутск Репутация: нет Всего: 1 |
Для метода GetData я так и делаю, а вот DENN как быть с конструктором?
Я бы хотел подключаться в другой DLL |
|||
|
||||
| DENNN |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3878 Регистрация: 27.3.2002 Где: Москва Репутация: 1 Всего: 43 |
В твоем случае, можно переписать объявление конструктора так:
Конечно метод не универсальный, но в твоем случае исправлений в коде почти не требуется. Можно предложить и другие "хитрые способы", но суть не измениться - C++ нельзя изменить порядок вызова базовых кострукторов (это основа механизма наследования). |
|||
|
||||
| Fantasist |
|
|||
|
Лентяй ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1517 Регистрация: 24.3.2002 Репутация: 4 Всего: 41 |
Для этого виртуальные методы не нужны совершенно. Способ предложенный DENN отлично используется и для не виртуальных методов. -------------------- Волны гасят ветер... |
|||
|
||||
| valex13 |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 29.1.2003 Где: Иркук. область, г . Иркутск Репутация: нет Всего: 1 |
Что касается конструктора DENN, ты абсолютно прав. Я так и сделаю Признаюсь, у меня была схожая мысль. Что-ж. Я ранее ( до того как задать вопрос ) делал так:
class A { public A() { LoadLibrary(LibraryName); } public A( newNameLibr) {LibraryName = newNameLibr; A();} } Таким образом: B var ("MyName"); А как быть, если у меня наследник в третьем колене? Есть A Есть B::A с простым конструктором и Есть С::B::A Что же касается виртуальных методов, то если не сделаешь в потомке метод виртуальным, то при вызове B::GetData вызовиться GetData предка. Даже если он переопределен. Или я ошибаюсь.... |
|||
|
||||
| RAN |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 709 Регистрация: 14.3.2003 Где: Щёлково Моск.обл. Репутация: 5 Всего: 6 |
Чепуха, достаточно только в классе предке поставить virtual и класс потомок сможет его перегружать. Там писать virtual все не обязательно, но я всегда пишу, чтоб было наглядно видно - метод перегружен, но это дело вкуса. Кстати, если бы даже метод не был виртуальным, то B::GetData() не мог бы всё равно вызывать метод предка A::GetData(), он бы вызывал свой метод. Так часто бывает с переменными, когда в двух классах, предке и потомке, одноимённые переменные, каждый будет видеть свою. Смысл виртуальных методов не только в том, что ты можешь заменить функцию класса-предка на новую (именно заменить, а не вызвать раньше), но и в том, что даже если ты преобразуешь объект класса потомка к классу предка, тот всё равно будет видеть функцию класса потомка. Полиморфизм, батенька - методы, реально, принадлежат не классу, а объекту, созданному на его основе :
|
||||
|
|||||
| Vyacheslav |
|
||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2124 Регистрация: 25.3.2002 Где: Москва Репутация: 9 Всего: 59 |
Ошибаешься. Переопредеялять можно и невиртуальные методы. Вся разница в работе виртуальных и невиртуальных методов начинает проявляться, когда задействуешь полиморфизм
результат паботы программы
-------------------- С уважением, Вячеслав Ермолаев |
||||||
|
|||||||
| valex13 |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 29.1.2003 Где: Иркук. область, г . Иркутск Репутация: нет Всего: 1 |
А если вот такая ситуация:
Есть А и наследник В Оба имеют один и тот же виртуальный метод OnCalc Делаю так: A *ab = new A(); B *bb = (A*)ab; bb->OnCalc(); и вызывается OnCalc() объекта A. А мне необходимо, чтобы вызывался метод объекта A? Это сообщение отредактировал(а) valex13 - 11.6.2003, 08:12 |
|||
|
||||
| valex13 |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 29.1.2003 Где: Иркук. область, г . Иркутск Репутация: нет Всего: 1 |
Извините
bb->OnCalc(); - это описка. |
|||
|
||||
| Vyacheslav |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2124 Регистрация: 25.3.2002 Где: Москва Репутация: 9 Всего: 59 |
Вопрос не ясен. Тебе нужен метод А, он и вызывается. Как ты и хотел -------------------- С уважением, Вячеслав Ермолаев |
|||
|
||||
| RAN |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 709 Регистрация: 14.3.2003 Где: Щёлково Моск.обл. Репутация: 5 Всего: 6 |
Повторюсь, методы пренадлежат объекту, а не классу, чтоб метод или переменная принадлежали классу они должны быть объявлены как static. Поэтому как ab не крути, будет вызываться A::OnCalc(), ты ведь написал new A(). Есть такое понятие - vtable. vtable - это таблица, в которой храняться ссылки на все методы и переменные. И когда ты определяешь в предке метод, как виртуальный, то при его появлении в потомке просто меняется адрес в vtable (запутанно объяснил, надеюсь кто-нибудь что-нибудь понял). Кстати, B* bb = (A*)ab; - совершенно бесполезная операция. ab итак типа A*, её незачем к A* преобразовывать, а bb типа B* и ab будет преобразована к B* в результате присвоения автоматически. Лично я в таких случаях преобразовываю явно, считаю что так правильнее: B* bb = (B*)ab; //порядок |
|||
|
||||
| Fantasist |
|
|||
|
Лентяй ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1517 Регистрация: 24.3.2002 Репутация: 4 Всего: 41 |
если уж так, то лучше пользоваться более правильным преобразованием dynamic_cast: B* bb = dynamic_cast<B*>(ab); или, если не хочеться, чтобы выполнялась динамическая проверка, то: B* bb = static_cast<B*>(ab); -------------------- Волны гасят ветер... |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |