Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Виртуальные функции.Что это такое? Часть2  (Прочитано 16611 раз)
0 Пользователей и 4 Гостей смотрят эту тему.
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« : 12-08-2005 14:44 » 

Меня смутил один момент, который бы мне очень хотелось разъяснить, чтобы не было сомнений
Цитата
Абстрактный класс нельзя применять для задания типа параметра функции, или в качестве типа возвращаемого значения. Его нельзя использовать при явном приведении типов. Зато можно определять ссылки и указатели на абстрактные классы.

Получается я не могу сделать так:
Код:
class base{
public:
virtual void f()=0;
}

class child:public base{
public:
virtual void f(){cout << child class;}
}

void func(base *p, child &ob)//Здесь я так понимаю кроется ошибка???
{
p=&ob;
p->f();
}

int main()
{
base *uk;
child ob;

func(uk, &ob);


return 0;
}


Пример может и глупый, но он содержит мой вопрос. Заранее благодарю за ответ и предупреждаю, что скорее всего будут еще вопросы Улыбаюсь.
Записан

ещё один вопрос ...
Alf
Гость
« Ответ #1 : 12-08-2005 20:21 » 

Абстрактный класс нельзя применять для задания типа параметра функции, или в качестве типа возвращаемого значения. Его нельзя использовать при явном приведении типов. Зато можно определять ссылки и указатели на абстрактные классы.

Список далеко не полный. Я бы сказал короче: абстрактный класс нельзя применять для инстанцирования, явного или неявного. Это включает в себя перечисленные в цитате случаи и еще массу неперечисленных.

Получается я не могу сделать так...

Это почему же? Можешь вполне. Хоть твоя цитата и не перечисляет все возможные случаи, но в ней явно оговаривается, что
Цитата
можно определять ссылки и указатели на абстрактные классы
Поскольку в твоем примере применен именно указатель на абстрактный класс, никакого криминала в нем нет.

Заранее благодарю за ответ и предупреждаю, что скорее всего будут еще вопросы Улыбаюсь.

Вот уж напугал так напугал  Ага
« Последнее редактирование: 12-08-2005 20:24 от Alf » Записан
Михалыч
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 13-08-2005 08:16 » 

Ага... Вот если бы ты попытался передать в функцию объект класса base, а не указатель на него, вот тогда бы да, была бы ошибка. Правда я не могу вот так, "с разбегу" придумать - зачем было бы передавать в функцию объект "по значению" Улыбаюсь
А так - все нормально, никакого криминала Улыбаюсь
Да, уж, предупредил! Улыбаюсь Ну, чтож - предупрежден - значит уже вооружен Улыбаюсь
Будем старательно готовиться к ответам Улыбаюсь
Записан

Поживем - увидим... Доживем - узнаем... Выживу - учту  Улыбаюсь
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 13-08-2005 10:09 » 

За ответ спасибо. Еще вопрос в качестве уточнения (все на примере той же функции func())

нельзя делать так
Код:
base func()
но можно
Код:
base* func()
нельзя делать так
Код:
base ob;
но можно
Код:
base *p;
Про приведение типов не совсем понял, т.е. я понял, что нельзя делать что-то типа этого
Код:
class base{
....
int i;
virtual int get()=0;
}
class child:public base{
...
int i;
int get(){return i;}
}

main()
{
base *p;
child ob;
(base)ob.i; //Здесь я так понимаю, кроется ошибка при попытке обратиться к переменной i класса base,
               // но ошибка связана с преобразованием типов

return;
}

« Последнее редактирование: 13-08-2005 10:49 от nikedeforest » Записан

ещё один вопрос ...
Михалыч
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 13-08-2005 14:38 » 

Я не совсем понял последнюю часть примера, с членами классов int i - так было задумано - что в каждом классе именно свой int i?
Насколько мне кажется такое приведение (base)ob.i; не законно. И опять же не понятно для меня - зачем такое использование? Хотя в жизни каких только задач не возникает Улыбаюсь
Вот такой пример применения абстрактного базового класса мне лично более понятен...
Берем твой класс base и несколько дочерних классов child1...child9, например. В каждом дочернем конечно же своя функция get(), которая делает что-нить ну очень уникальное для своего класса.
Создаем массив указателей на  base класс
base * p[9];
и спихиваем в него указатели на объекты дочерних классов, приводя их к типу указателя на базовый класс
что-то типа p[5]=(base *) new child5(...);
Теперь перебирая элементы массива спокойно по указателю вызываем функцию get(), а она уже делает абсольтно разные - но конкретные для своего класса вещи Улыбаюсь
« Последнее редактирование: 13-08-2005 14:40 от Михалыч » Записан

Поживем - увидим... Доживем - узнаем... Выживу - учту  Улыбаюсь
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 13-08-2005 14:50 » 

C последним примером я был не прав вообще, даже если класс base не был бы абстрактным, то такое приведение типов все равнго ошибочно.

С примером разобрался. А свои примеры я приводил с целью того, чтобы вы подтвердили правильно-ли я понял данные моменты или я где-то ошибаюсь.
Записан

ещё один вопрос ...
Alf
Гость
« Ответ #6 : 13-08-2005 19:02 » 

Главное - запомни очень простую вещь. На абстракнтый класс можно ссылаться, т.е. создавать указатель на него. Абстрактный класс нельзя инстанцировать, т.е. создавать экземпляр. Отсюда вытекают ответы на все уже заданные вопросы и на те, что еще не успел задать.

За ответ спасибо. Еще вопрос в качестве уточнения (все на примере той же функции func())

нельзя делать так
Код:
base func()
но можно
Код:
base* func()
нельзя делать так
Код:
base ob;
но можно
Код:
base *p;
Про приведение типов не совсем понял, т.е. я понял, что нельзя делать что-то типа этого
Код:
class base{
....
int i;
virtual int get()=0;
}
class child:public base{
...
int i;
int get(){return i;}
}

main()
{
base *p;
child ob;
(base)ob.i; //Здесь я так понимаю, кроется ошибка при попытке обратиться к переменной i класса base,
 // но ошибка связана с преобразованием типов

return;
}

Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 14-08-2005 17:50 » new

Alf, я понял, спасибо!
Записан

ещё один вопрос ...
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines