Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.04.2013, 20:51   #1
SAMOUCHKA
Форумчанин
 
Регистрация: 07.08.2011
Сообщений: 576
По умолчанию виртуальный полиморфизм

Допустим есть класс где несколько чисто виртуальных функций. Этот класс наследуют несколько классов. Как известно в классах наследниках все эти функции на определять, иначе будет ошибка, сам руками проверял. Наверно с++ разрабатывали умные башки, но я все равно ни как не додумаюсь -что было бы ели бы разрешалось определять не все функции? Ну скажем в одном классе определил все функции, а в другом только одну. Вероятно это приводило бы к каким то конфликтам и ошибкам, но к каким?
Объясните для чего так сделано.
SAMOUCHKA вне форума Ответить с цитированием
Старый 05.04.2013, 21:10   #2
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

http://devdoc.web-ide.ru/index.php/c...rtual_base.htm

От себя добавлю:

Чисто-виртуальные функции нужны для задания интерфейса всех будущих потомков. Для них допустимо иметь реализацию. Хотя по большому счету в этом нет никакого смысла.

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

Достаточно сделать просто виртуальными с реализациями.
_Bers вне форума Ответить с цитированием
Старый 05.04.2013, 21:45   #3
SAMOUCHKA
Форумчанин
 
Регистрация: 07.08.2011
Сообщений: 576
По умолчанию

Цитата:
Если хочется переопределять только часть функций, значит нет никакого смысла в базовом классе объявлять их все, как чисто-виртуальные.
Согласен с вами.
Но тем не менее почему, в каком то из потомков, не разрешается определять только часть функций?
SAMOUCHKA вне форума Ответить с цитированием
Старый 05.04.2013, 22:05   #4
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от SAMOUCHKA Посмотреть сообщение
Согласен с вами.
Но тем не менее почему, в каком то из потомков, не разрешается определять только часть функций?
Выше я давал ссылку.
_Bers вне форума Ответить с цитированием
Старый 05.04.2013, 22:17   #5
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Код:
#include <iostream>

using namespace std;

class A {
public:
    virtual void f() = 0;
    virtual void g() = 0;
};

class B: public A {
public:
    virtual void f() {
        cout << "B::f" << endl;
    }
};

class C: public B {
public:
    virtual void g() {
        cout << "C::g" << endl;
    }
};

int
main()
{
    //A a; ошибка
    //B b; ошибка
    C c;
    c.f();
    c.g();
    return 0;
}
Можно в классе потомке определять не все функции, но тогда этот потомок будет оставаться абстрактным классом, то есть нельзя будет создавать объекты этого класса.
Цитата:
Ну скажем в одном классе определил все функции, а в другом только одну.
Ну хорошо. Разрешили. Что дальше? Как программа должна понять, что делать при вызове чисто виртуальной функции? Тела-то ее нету.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 05.04.2013 в 22:20.
BDA на форуме Ответить с цитированием
Старый 05.04.2013, 23:03   #6
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
Ну хорошо. Разрешили. Что дальше? Как программа должна понять, что делать при вызове чисто виртуальной функции? Тела-то ее нету.

1. Чисто-виртуальная функция может иметь туловище, а может и не иметь (как и любая другая функция).

http://liveworkspace.org/code/1qEFsX$3

2. Линкер в состоянии пропасти, есть у функции туловище или нет (как и для любой другой функции)

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

Тем не менее, делать это запрещено по стандарту.
_Bers вне форума Ответить с цитированием
Старый 05.04.2013, 23:28   #7
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Цитата:
Таким образом, технически не существует причин, по которым невозможно было бы создать экземпляр абстрактного класса, при условии, что у вызываемых чисто-виртуальных функций есть туловища.
Эти туловища "практически" делают чисто виртуальную функцию просто виртуальной (по стандарту это не так, но по виду программы очень похоже).
В более глубокую дискуссию не могу вступить - не хватает знаний.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA на форуме Ответить с цитированием
Старый 06.04.2013, 04:46   #8
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
Эти туловища "практически" делают чисто виртуальную функцию просто виртуальной (по стандарту это не так, но по виду программы очень похоже).
В более глубокую дискуссию не могу вступить - не хватает знаний.
Природа Чисто-виртуальных функций ничем не отличается от природы обычных виртуальных функций. В их основе так же лежит таблица указателей на функции.

Вообще то, идеологически грамотный интерфейс лишь объявляет функционал, которые реализуют потомки. И не нуждается в реализации оных.

Чисто-виртуальные функции, это - языковый механизм, позволяющий объявлять функции без их реализации, и гарантировать времени компиляции (то есть это сможет сделать компилятор ещё до компоновки), что контракт будет выполнен. То бишь, что ошибок линковки не будет.

В действительности, я не могу себе представить ни одной реальной причины, зачем вообще чисто-виртуальной функции может понадобится туловище, за исключением ситуации, когда этой функцией является диструктор, и он - единственный явно объявленный метод в классе, не считая конструктора.
_Bers вне форума Ответить с цитированием
Старый 06.04.2013, 09:41   #9
SAMOUCHKA
Форумчанин
 
Регистрация: 07.08.2011
Сообщений: 576
По умолчанию

Цитата:
Ну хорошо. Разрешили. Что дальше? Как программа должна понять, что делать при вызове чисто виртуальной функции? Тела-то ее нету.
На мой взгляд было бы гораздо гибче если разрешить определять не все функции. А если какая то не определена значит она не нужна в данном классе и ее вызов запретить.
Таким образом используется только тот интерфейс который нужен в данном классе. И тут появилось бы большее различие между виртуальной и чисто виртуальной функциями .
Такое мое мнение.
SAMOUCHKA вне форума Ответить с цитированием
Старый 06.04.2013, 10:45   #10
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Цитата:
Сообщение от SAMOUCHKA Посмотреть сообщение
Таким образом используется только тот интерфейс который нужен в данном классе.
Если у вас есть методы интерфейса, которые нужны в разных имплементациях, то значит ваш интерфейес плохо спроектирован - следует эти методы вынести в разные интерфейсы.
waleri вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Полиморфизм Кудаив Помощь студентам 3 20.05.2012 14:03
Полиморфизм. Wa1demar Общие вопросы C/C++ 0 04.03.2012 14:23
Полиморфизм Zorgan Visual C++ 22 29.08.2011 12:23
Полиморфизм MasterSporta Общие вопросы C/C++ 3 10.04.2011 23:46
Полиморфизм mister2010 Общие вопросы C/C++ 30 24.05.2010 01:07