4 / 4 / 0
Регистрация: 24.10.2010
Сообщений: 200
|
|
1 | |
Виртуальный методы, абстрактный класс.26.02.2012, 22:50. Показов 7728. Ответов 16
Метки нет (Все метки)
Здравствуйте.
Теоретические вопросы. Что такое виртуальный методы и что такое абстрактный класс. Можете объяснить своими словами без ссылок на википедию. Заранее спасибо.
0
|
26.02.2012, 22:50 | |
Ответы с готовыми решениями:
16
Виртуальный абстрактный класс Абстрактный класс. Виртуальный метод, который возвращает T- тип Абстрактный класс «Клиент банка», имеющий виртуальный метод для вывода данных о клиенте Абстрактный класс, виртуальные методы |
117 / 74 / 6
Регистрация: 23.01.2012
Сообщений: 186
|
|
26.02.2012, 23:40 | 2 |
Если несколько упрощать:
Абстрактный класс - Класс который описывает только прототипы функций без их реализации(в терминологии С++ интерфейс) , соответственно раз нет реализации не одного метода(функции), то нельзя создать экземпляр этого класса. Используется для того что бы все наследники этого класса имели не взирая, что они делают, единый интерфейс(вызов методов). Виртуальный метод (функция) - Это такая функция которая переписана для каждого наследника класса. И определения какую функцию вызывать, программа будет решать не в момент написания кода, а в момент его выполнения. Допустим у вас три класcа: B - базовый N1 - наследник от B N2 - наследник от B или N1 во всех трех классах есть виртуальная функция "V" которая в разных классах выполняет различные действия. И есть в программе функция "f" которая в качестве аргумента получает указатель на базовый класс и имеет следущею реализацию В->V(); Теперь в эту функцию, Вы можете передать в качестве аргумента, класс B или N1 или N2 и будет выполнена функции V именно того класса который Вы передали. Ну если коротенько, то гдето так.
2
|
5057 / 3117 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
|
|
27.02.2012, 23:55 | 3 |
Не обязательно. Чтобы быть абстрактным, класс должен содержать чистую виртуальную функцию. Из такого определения вытекает, что класс может содержать 100 обычных функцию с реализациями (даже не виртуальных) и одну чистую виртуальную, и тогда он будет абстрактным.
В терминологии С++ как раз-таки нет понятия "интерфейсы". Так что это замена интерфейсам. С другой стороны, в таких языках, как Java и C# есть как интерфейсы, так и абстрактные классы. И снова - достаточно, чтобы не было реализации хотя бы одного метода (он должен быть объявлен как чисто виртуальный - virtual type method(parameters) = 0;), то нельзя создать объект такого класса, потому что он становится абстрактным. Независимо от реализаций и виртуальности остальных его методов. Не обязательно. Класс-наследник может безболезненно использовать реализацию класса-родителя. Виртуальный метод - это метод, конкретная реализация которого определяется во время исполнения программы на основании типа объекта, из которого был вызван метод.
1
|
44 / 44 / 17
Регистрация: 28.01.2012
Сообщений: 341
|
||||||
22.05.2013, 00:52 | 4 | |||||
А у меня есть такой вопрос по абстрактным классам и виртуальным функциям.
Если в абстрактном классе, к примеру 2 виртуальные функции (не важно чисто виртуальные или нет), то в производном классе не могут же существовать другие методы, кроме этих 2-х переопределенных? Точнее они могут существовать, но если что-то типа такого
0
|
5057 / 3117 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
|
|
22.05.2013, 12:16 | 5 |
Разумеется. Родитель ничего не знает о дополнениях, добавленных в наследнике, в том числе о новых методах. А раз этого не знает родитель, то этого не знает и компилятор, поэтому в случае попытки вызова метода, появившегося только в потомке, компилятор скажет, что такого метода в предке не существует. С тем же успехом можно попытаться вызвать через указатель на наследника метод, которого вообще нет ни в одном классе программы.
1
|
:)
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
|
||||||
22.05.2013, 12:54 | 6 | |||||
Если нужно вызвать метод дочернего класса (которого не было в базовом), имея только указатель базового типа, то можно использовать приведение типа:
1
|
5057 / 3117 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
|
|
22.05.2013, 13:17 | 7 |
Да, этот способ имеет место быть. Но зачастую его применение говорит об изначальной непродуманности самой архитектуры.
А вот это надо делать не "по-хорошему", а всегда.
0
|
5057 / 3117 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
|
|
22.05.2013, 13:28 | 9 |
Если в данном случае используется такой подход, то проблема не в архитектуре, а в голове автора (к вам, разумеется, не относится, ибо это пример). Не могу представить себе ситуацию, когда на одной странице кода было бы видно создание объекта дочернего класса, присваивание его адреса ссылке/указателю на базовый класс, и приведение этой ссылки/указателя к ссылку/указателю на дочерний класс. Но, в любом случае, я бы всё равно сделал проверку. Код имеет свойство разрастаться, при этом и посредством вклинивания новых строк между существующими.
0
|
44 / 44 / 17
Регистрация: 28.01.2012
Сообщений: 341
|
||||||
22.05.2013, 19:34 | 10 | |||||
А если делать проверку то у меня работает только так:
0
|
5057 / 3117 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
|
||||||
22.05.2013, 19:38 | 11 | |||||
akk, потому что pointer[i] имеет тип ClassBase *, к которому во время присваивания автоматически приводится указатель, полученный после dynamic_cast. Делать надо так:
А вообще, какое отношение проверяемый pointer[i] имеет к goods[i], из которого вызывается метод? Если вызываете из goods[i], то и проверять надо именно его.
1
|
44 / 44 / 17
Регистрация: 28.01.2012
Сообщений: 341
|
|
22.05.2013, 19:40 | 12 |
silent_1991, т е надо использовать другой временный указатель подкласса, и под ним выполнять методы? Но так данные не потеряются?
0
|
5057 / 3117 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
|
|
22.05.2013, 19:40 | 13 |
akk, а куда они потеряются-то? Это же указатель, а не копия объекта.
0
|
44 / 44 / 17
Регистрация: 28.01.2012
Сообщений: 341
|
||||||
22.05.2013, 19:54 | 14 | |||||
Ну так если память выделяется динамически, а потом происходит приведения к другому типу, и заполняется методами подкласса?
Добавлено через 9 минут И если к примеру имеется еще один указатель базового класса, то можно сделать просто так или тоже надо приводить.
0
|
5057 / 3117 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
|
|
22.05.2013, 20:10 | 15 |
akk, вам бы подучить основы, а потом уже приступать к полиморфизму. Никакая память никакими методами не заполняется. Вы полагаете, что каждый объект хранить все методы своего класса? Это неверно. Методы в программе располагаются в единственном экземпляре. Полиморфизм работает благодаря тому, что каждый объект хранит ссылку на таблицу виртуальных методов своего класса. Т.е. в vtable объекта типа ChildClass есть указатели на все виртуальные методы ChildClass, в том числе на те, которых нет в BaseClass. Но если адрес этого объекта присвоен указателю на BaseClass, компилятор просто не знает, что по этому указателю на самом деле лежит объект типа ClassChild с расширенной по отношению к BaseClass таблицей виртуальных методов. Приведение вниз посредством dynamic_cast заставляет компилятор понять, что на самом деле используется vtable класса ChildClass, и позволить нам вызвать методы, добавленные в этом классе.
Код вашего примера не понял, как и вопроса касательно него. В данном случае pointer1 и pointer2 в конечном счёте будут указывать на один и тот же объект типа ChildClass. Если хотите вызывать методы, добавленные в ChildClass, как через pointer1, так и через pointer2 - надо делать приведение вниз. Добавлено через 6 минут Вернее сказать даже не так. dynamic_cast играет роль только во время выполнения. Компилятору наплевать на vtable, ему важно, чтобы тип указателя, через который вызывается метод, содержал этот вызываемый метод.
1
|
44 / 44 / 17
Регистрация: 28.01.2012
Сообщений: 341
|
||||||
22.05.2013, 20:14 | 16 | |||||
0
|
5057 / 3117 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
|
|
22.05.2013, 20:16 | 17 |
За исключением того, что в строках 3 и 10 нужно использовать разные имена, да, не вижу препятствий сделать так (как не вижу и того, что вас смущает в этом коде).
1
|
22.05.2013, 20:16 | |
22.05.2013, 20:16 | |
Помогаю со студенческими работами здесь
17
Объясните как объявить абстрактный класс, и при этом не тащить виртуальные методы в производные классы абстрактный класс как реализовать данные, над которыми методы выполняют какие-либо действия Опишите абстрактный базовый класс "строка",реализующий методы ввода-вывода строки Класс: Разработать абстрактный класс класс Point для задания координаты... Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Блоги программистов | |||||
Как использовать GraphQL в C# с HotChocolate
Programming 05.01.2025
GraphQL — это современный подход к разработке API, который позволяет клиентам запрашивать только те данные, которые им необходимы. Это делает взаимодействие с API более гибким и эффективным по. . .
|
Модель полного двоичного суматора с помощью логических операций (python)
AlexSky-coder 04.01.2025
def binSum(x:list, y:list):
s=^y]
p=x and y
for i in range(1,len(x)):
s. append((x^y)^p)
p=(x and y)or(p and (x or y))
return s
x=list()
y=list()
|
Это мы не проходили, это нам не задавали...(шестибитный асихронный счётчик с управляющим сигналом заде
Hrethgir 04.01.2025
Асинхронный счётчик на сумматорах (шестиразрядный по числу диодов на плате, но наверное разрядов будет больше - восемь или шестнадцать, а диоды на старшие), так как триггеры прошли тестирование и. . .
|
Руководство по созданию бота для Телеграм на Python
IT_Exp 04.01.2025
Боты для Телеграм представляют собой автоматизированные программы, которые выполняют различные задачи, взаимодействуя с пользователями через интерфейс мессенджера. В данной статье мы рассмотрим,. . .
|
Применение компонентов PrimeVue в Vue.js 3 на TypeScript
BasicMan 04.01.2025
Введение в PrimeVue и настройка окружения
PrimeVue представляет собой мощную библиотеку компонентов пользовательского интерфейса для Vue. js 3, которая предоставляет разработчикам богатый набор. . .
|
Как стать Senior developer
cpp_developer 04.01.2025
В современной индустрии разработки программного обеспечения позиция Senior Developer представляет собой не просто следующую ступень карьерной лестницы, а качественно новый уровень профессионального. . .
|
Что известно о дате выхода Windows 12 и чего от нее ждать
IT_Exp 04.01.2025
В мире технологий постоянно происходят изменения, и операционные системы не являются исключением. Windows 11, выпущенная в октябре 2021 года, принесла множество инноваций и улучшений, но. . .
|
Что новенького в .NET Core 9
Programming 04.01.2025
Обзор ключевых изменений в . NET Core 9
Платформа . NET Core продолжает активно развиваться, и версия 9 представляет собой значительный шаг вперед в эволюции этой технологии. Новый релиз. . .
|
Инструкция по установке python3.13.1 в Debian 12
AlexSky-coder 03.01.2025
sudo apt update
sudo apt install build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev
wget. . .
|
Затестил триггеры. архив проекта прилагаю с GOA файлами в настройках архиватора проектов.
Hrethgir 03.01.2025
В этот раз нет закольцованности, потому что от неё только глюки, как я понял, логика не вырезанная. Триггеры очень быстрые если верить измерениям с помощью анализатора от Gowin.
Есть ещё регистры,. . .
|
Python в помощь DevOps
IT_Exp 03.01.2025
Причины использования Python в работе DevOps
Python стал неотъемлемой частью мира DevOps, и это не случайно. Этот язык программирования обладает множеством преимуществ, которые делают его. . .
|
Angular vs React vs Vue.js
BasicMan 03.01.2025
О, друзья-разработчики и просто любопытные читатели! Сегодня мы отправимся в увлекательное путешествие по миру фронтенд-разработки, и первой остановкой станет Angular – этакий строгий немецкий. . .
|