![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| mrgloom |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 829 Регистрация: 8.6.2011 Репутация: нет Всего: нет |
Почему нельзя создать объект абстрактного класса? но можно создать на него указатель.
(непонятно именно с логической точки зрения). потому что создав указатель всё равно можно навредить
Это сообщение отредактировал(а) mrgloom - 17.5.2013, 15:29 |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
mrgloom, указатель не создают... навредить можно еше тысячей разных способов.. при этом, что указанный вред никак не связан с абстрактным классом.. и.. "не навреди" единным жив программист.... Это сообщение отредактировал(а) mes - 19.5.2013, 09:39 |
|||
|
||||
| Arantir |
|
|||
|
Рыбак без удочки ![]() ![]() Профиль Группа: Участник Сообщений: 960 Регистрация: 18.11.2012 Репутация: 1 Всего: 55 |
Можно создать указатель, в который можно поместить объект, наследующий этот класс. Это просто будет значить, что объект в указателе (точнее, на который этот указатель указывает) обязательно должен быть наследником этого абстрактного класса. В других языках для этого существуют еще и интерфейсы.
Программиста от собственного ума ничего не спасет. Это сообщение отредактировал(а) Arantir - 17.5.2013, 15:55 -------------------- interface Жопа { // ATTENTION: has to be implemented by every class of the project for proper project work } |
|||
|
||||
| NoviceF |
|
||||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 13.3.2012 Где: Ростов-на-Дону Репутация: нет Всего: 2 |
как уже в общем написали выше, через указатель на базовый класс можно обращаться к наследникам этого базового класса, это называется динамический полиморфизм. вот тебе ещё на тему
http://stackoverflow.com/questions/2505328...l-class-pointer тоже всё будет работать, пока нет обращения к членам данным. То есть можно забыть создать или проинициализировать член данное в классе (если обращение к нему происхоодит через указатель), а потом появятся загадочные падения в конструкторе копирования, например
про указатель это так.. из практики
Это сообщение отредактировал(а) NoviceF - 17.5.2013, 16:57 |
||||||||
|
|||||||||
| mrgloom |
|
||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 829 Регистрация: 8.6.2011 Репутация: нет Всего: нет |
объявляют? т.е. как бы создание класса предполагает собой создание чего(выделение памяти), а указатель просто указатель на такой то тип? но так же можно было бы и создать "пустой" класс, где какое то поле не опеределено или какой то метод. так что непонятно такое ограничение.
ну имхо это интуитивно\логически неправильно, хотя понятно что это "фича" языка. Добавлено через 2 минуты и 41 секунду хотя опять же есть static функции которыми можно пользоваться без создания класса. Добавлено через 5 минут и 43 секунды но вопрос то не в этом, а в том почему нельзя определить класс с абстрактным методом. Добавлено через 7 минут и 14 секунд
|
||||||
|
|||||||
| Guinness |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 310 Регистрация: 21.6.2009 Где: Зеленоград Репутация: нет Всего: 10 |
Если я ничего не путаю, то это не фича языка. При компиляции обычные функции класса компилируются в определенный раздел exe-шника. И для любового экзепляра класса будут вызываться функции хранящиеся в одной области памяти. (Может быть ошибаюсь, но мне когда-то так объясняли работу вышеуказанного кода). К слову этот код должен ломаться, если сделать данную функцию объявить виртуальной. Т.к. для каждого экземпляра класса создается своя таблица виртульных функций. |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
||||
|
||||
| Arantir |
|
|||
|
Рыбак без удочки ![]() ![]() Профиль Группа: Участник Сообщений: 960 Регистрация: 18.11.2012 Репутация: 1 Всего: 55 |
Ага, называется NULL. Дело в том, что это логическая бомба. Если метод имеет тип возвращаемого значения, то программа ожидает это значение в 100% вызовов этого метода. Вызывать абстрактный метод априори не имеет смысла. Если вам нужно создавать экземпляр класса, зачем его вообще делать абстрактным? То, что вам нужно, можно и нужно реализовывать своими руками. Если вам нужны пустые методы для переопределения в наследниках, то для этого существуют виртуальные методы:
переопределенные в дочернем классе, они заменят родительский метод даже, если указатель будет иметь тип родительского. В то же время можно создать экземпляр родительского класса. А при потребности можно выбросить исключение при вызове не переопределенного метода. Абстрактный класс предназначен именно для случая, когда его экземпляр не должен создаваться по замыслу разработчика. Кроме того, в C++ абстрактный класс так же может являться и интерфейсом. Это значит, что разработчик требует, чтобы в задуманных местах объекты в любом случае имели предусмотренные поля и методы. При этом класс, описывающих набор этих методов, является лишь шаблоном (такой себе инструкцией) и заведомо не нуждается в создании своих экземпляров. Это сообщение отредактировал(а) Arantir - 20.5.2013, 13:19 -------------------- interface Жопа { // ATTENTION: has to be implemented by every class of the project for proper project work } |
|||
|
||||
| volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
Нельзя и всё! Воспринимайте как данность. Вообще, сделано для удобства программиста. Например, если в наследнике вы забудете определить какой-то абстрактный метод, то компилятор вам об этом ненавязчиво напомнит. |
|||
|
||||
| mrgloom |
|
||||||||||||||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 829 Регистрация: 8.6.2011 Репутация: нет Всего: нет |
Так получается я всегда предполагается использовать только производный класс?
т.е. не
а
http://publib.boulder.ibm.com/infocenter/l...f%2Fcplr142.htm так зачем мне может понадобиться ссылка на базовый класс?или в 1 месте я могу унаследовать 1 метод, в другом другой типа
еще вопрос с примером
зачем нужна ссылка на базовый клас в производном классе?
в BestOf2NearestMatcher::match первой строчкой вызывается оператор ()
в переопределенном операторе
и match используется уже от BestOf2NearestMatcher? причем мы нигде не указали, что impl_ должен использовать BestOf2NearestMatcher::match. + получается что BestOf2NearestMatcher::match внутри BestOf2NearestMatcher::match и рекурсия?(вообщем этот момент непонятен) и что делает ?
|
||||||||||||||||||
|
|||||||||||||||||||
| Arantir |
|
|||
|
Рыбак без удочки ![]() ![]() Профиль Группа: Участник Сообщений: 960 Регистрация: 18.11.2012 Репутация: 1 Всего: 55 |
mrgloom, Ваша проблема в том, что Вы рассматриваете программу, как черный ящик. Попробуйте начать рассматривать ее как белый ящик.
Вы сами решаете, что предполагается использовать. И на основе этого создаете структуру программы. если предполагается любой класс с неким методом, то вы делаете указатель на абстрактный класс с этим методом. если предполагается конкретный Вами же написанный класс, то абстрактный класс для него не нужен. Почитайте про фреймворки... Абстрактные классы весьма полезны, если предполагается, что ваш код — только каркас, и тот, кто его использует, часть функционала будет реализовать самостоятельно в виде собственных классов. Чтобы фреймворк мог эти классы использовать, то и используются указатели с типом абстрактного класса. В такой указатель может быть помещен объект класса, созданного пользователем фреймворка. -------------------- interface Жопа { // ATTENTION: has to be implemented by every class of the project for proper project work } |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
mrgloom, очень сложные программы пишутся в виде модулей. Так удобнее писать и проще обслуживать. Возьмем для примера ядро Linux. Оно хоть и на С написано, но ООП там используется в полный рост.
Есть в нем некая подсистема. Устройств этого типа может быть куча, поэтому сразу же делается интерфейс для драйвера. Допустим, у драйвера должно быть 3 метода (ioctl, read, write). Вот разработчик подсистемы и делает класс с 3-мя чисто виртуальными функциями. Вся подсистема работает и взаимодействует с устройством через этот интерфейс. Затем другой разработчик решил написать драйвер для устройства Х. Он пишет наследника класса-интерфейса и переопределяет эти методы. Теперь, подсовывая объект драйвера, подсистема начинает работать полноценно. |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Это не ссылка на базовый класс - это ссылка на реализацию самого BestOf2NearestMatcher, причем она [реализация] находится не в родителе класса, а задается где то отдельно, снаружи. Это классическая реализация паттерна PIMPL
Нет. Эти match вызываются от разных объектов |
|||
|
||||
| mrgloom |
|
||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 829 Регистрация: 8.6.2011 Репутация: нет Всего: нет |
всё таки я не понял.
откуда берется match? я так понимаю, что если
то match должна быть определена в классе наследнике, собственно говоря BestOf2NearestMatcher::match но в ней первая же строчка непонятно для чего служит.
impl_ как я понял нужно для того чтобы можно был овызывать функции из класса FeaturesMatcher, хотя зачем это нужно если мы и так от него унаследовались. Это сообщение отредактировал(а) mrgloom - 21.5.2013, 12:24 |
||||||
|
|||||||
| xvr |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Именно так А вот это и есть вызов реализации. impl_ здесь смотрит не на родителя, а на другой экземпляр наследника FeaturesMatcher
Мы не себя вызываем, а другого наследника. Класс FeaturesMatcher (и его наследники, в частности BestOf2NearestMatcher) описывают единственный тип, а вот экземпляров этих типов (т.е. непостредственно объектов) может быть созданно много. И при вызове метода происходит вызов именно от экземпляра объекта, а не от самого класса/типа. |
||||
|
|||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |