Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/29: Рейтинг темы: голосов - 29, средняя оценка - 4.83
1 / 1 / 0
Регистрация: 27.07.2013
Сообщений: 8
1

Невиртуальный и виртуальный вызовы метода

19.06.2014, 08:29. Показов 5575. Ответов 4
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день, форумчане. Начал изучать C# и, читая книгу рихтера "CLR via C#" столкнулся с таким понятиям, как невиртуальный вызов виртуального метода. Не могли бы вы пояснить, что это значит - поиски в гугле увенчались неуспехом. Спасибо за внимание.
1
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.06.2014, 08:29
Ответы с готовыми решениями:

Что такое виртуальный и относительный виртуальный адрес?
Прив. Хочу разобрать одну программку, дизассемблировал ее и начал разбиратся. При помощи API...

Невозможно передать ArrayList в аргументы метода без модификатора static у этого метода или метода main
Крч, хочу передать экземпляр класса ArrayList в метод, но ide говорит, что нельзя это сделать, пока...

Полиморфизм: вызов метода базового класса, переопределенного метода и нового метода
В базовом классе метод помечен как virtual. Насколько я понял из книги: override означает, что...

Нужно клонировать виртуальный жесткий диск из RAID 0 на виртуальный жесткий диск в RAID 1 (зеркало)
Здравствуйте, очень надеюсь на вашу помощь. Сижу на работе 2ое суток. Есть intel embedded raid...

4
Эксперт .NET
5534 / 4298 / 1217
Регистрация: 12.10.2013
Сообщений: 12,332
Записей в блоге: 2
19.06.2014, 09:53 2
SmirnIL, может что-то типа такого...
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication4
{
    class Program
    {
        static void Main(string[] args)
        {
            B b = new B();
            b.Method();
            ((A)b).Method();
            Console.ReadLine();
        }
    }
    public class A
    {
        public virtual void Method()
        {
            Console.WriteLine("Virtual Method's call");
        }
    }
    class B : A
    {
        public new void Method()
        {
            Console.WriteLine("NonVirtual Method's call");
        }
    }
}
0
1 / 1 / 0
Регистрация: 27.07.2013
Сообщений: 8
19.06.2014, 10:29  [ТС] 3
В данном случае, по-моему выходит, что просто вызывается виртуальный метод и невиртуальный метод. В этом вроде бы разобрался, но что такое невиртуальный вызов виртуального метода моя голова никак не хочет осознать))
0
Эксперт .NET
17688 / 12873 / 3366
Регистрация: 17.09.2011
Сообщений: 21,138
19.06.2014, 11:08 4
Лучший ответ Сообщение было отмечено SmirnIL как решение

Решение

Цитата Сообщение от 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
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.06.2014, 11:43
Помогаю со студенческими работами здесь

Системные вызовы
Дали задание: • Вывести имя компьютера; • Вывести имя пользователя; • Вывести версию ядра...

Обратные вызовы
Здорова господа! Я от решаю задачку: Напишите класс или шаблон, подходящие для реализации обратных...

Cис. вызовы
Доброго времени суток, подскажите ошибку в коде, а то уже пару дней голову ломаю - не компилица......

Не понимаю вызовы
Абсолютно не понимаю вызовы. Учусь по книге Страуструпа. ... void print_square(int v); { ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru