1 / 1 / 0
Регистрация: 27.07.2013
Сообщений: 8
|
|
1 | |
Невиртуальный и виртуальный вызовы метода19.06.2014, 08:29. Показов 5575. Ответов 4
Метки нет (Все метки)
Добрый день, форумчане. Начал изучать C# и, читая книгу рихтера "CLR via C#" столкнулся с таким понятиям, как невиртуальный вызов виртуального метода. Не могли бы вы пояснить, что это значит - поиски в гугле увенчались неуспехом. Спасибо за внимание.
1
|
19.06.2014, 08:29 | |
Ответы с готовыми решениями:
4
Что такое виртуальный и относительный виртуальный адрес? Невозможно передать ArrayList в аргументы метода без модификатора static у этого метода или метода main Полиморфизм: вызов метода базового класса, переопределенного метода и нового метода Нужно клонировать виртуальный жесткий диск из RAID 0 на виртуальный жесткий диск в RAID 1 (зеркало) |
19.06.2014, 09:53 | 2 | |||||
SmirnIL, может что-то типа такого...
0
|
1 / 1 / 0
Регистрация: 27.07.2013
Сообщений: 8
|
|
19.06.2014, 10:29 [ТС] | 3 |
В данном случае, по-моему выходит, что просто вызывается виртуальный метод и невиртуальный метод. В этом вроде бы разобрался, но что такое невиртуальный вызов виртуального метода моя голова никак не хочет осознать))
0
|
17688 / 12873 / 3366
Регистрация: 17.09.2011
Сообщений: 21,138
|
|
19.06.2014, 11:08 | 4 |
Сообщение было отмечено SmirnIL как решение
Решение
Ну смотрите, зачем вообще нужен виртуальный вызов? А затем, что существует такая штука, как наследование и полиморфизм, а значит переменная х, имеющая тип Т1, не обязательно должна ссылаться на объект типа Т1. Она может вполне ссылаться на объект типа Т2, который наследуется от Т1. Если некий метод является виртуальным, то при его вызове нужно определить, на объект какого именно типа ссылается переменная х, чтобы отработать метод, переопределенный на нужном типе. Этим и занимается виртуальный вызов: определяет фактический тип объекта, на который ссылается x и вызывает метод на этом типе (или на ближайшем переопределившем).
Понимая это, довольно просто сделать вывод о том, когда виртуальный метод можно вызывать невиртуально, то есть без определения фактического типа объекта: тогда, когда однозначно известно, что переменная х ссылается именно на тип Т1, а не Т2 или Т3. Очевидные примеры — это структуры, в которых наследование отсутствует в принципе, а следовательно если есть переменная х, имеющая тип структуры S1, в которой переопределен виртуальный метод ToString, то при вызове этого метода на переменной х рантайму не надо предполагать, что может быть какой-то тип S2, наследующийся от S1 и снова переопределивший этот метод. У структур нет наследования, потому компилятор может смело делать невиртуальный вызов, то есть напрямую на типе S1. Это же касается и "запечатанных" классов (sealed). Если есть некая переменая х, ссылающаяся на тип Т2, который наследуется от Т1, но помечен как sealed, то при вызове того же ToString при условии, что он переопределен в T2, нет необходимости делать виртуальный вызов, так как переменная типа Т2 не может ссылаться на какой-нибудь Т3, потому как sealed запрещает наследование. С sealed-методами та же история. Есть и другие нюансы, когда делается невиртуальный вызов (например, при вызове родительского метода из переопределенного), но это не такие очевидные примеры.
7
|
1 / 1 / 0
Регистрация: 27.07.2013
Сообщений: 8
|
|
19.06.2014, 11:43 [ТС] | 5 |
kolorotur, большое спасибо! Разобрался
0
|
19.06.2014, 11:43 | |
19.06.2014, 11:43 | |
Помогаю со студенческими работами здесь
5
Системные вызовы Обратные вызовы Cис. вызовы Не понимаю вызовы Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |