Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.02.20;
Скачать: [xml.tar.bz2];

Вниз

Overriding versus hiding   Найти похожие ветки 

 
Bless ©   (2005-02-02 14:36) [0]

Процитирую целиком текст справки из сабжевого раздела.


If a method declaration specifies the same method identifier and parameter signature as an inherited method, but doesn"t include override, the new declaration merely hides the inherited one without overriding it. Both methods exist in the descendant class, where the method name is statically bound. For example,


type
 T1 = class(TObject)
   procedure Act; virtual;
 end;
 T2 = class(T1)
   procedure Act;  // Act is redeclared, but not overridden
 end;
var
 SomeObject: T1;
begin
 SomeObject := T2.Create;
 SomeObject.Act;  // calls T1.Act
end;


Объясните пожалуйста, почему строчка SomeObject.Act приводит к вызову метода Act из класса T1?


 
REA   (2005-02-02 14:42) [1]

Компилятор знает, что SomeObject: T1 и вызывает метод T1.Act. Про метод T2.Act ему не известно в контексте этого объекта.


 
icWasya ©   (2005-02-02 15:24) [2]

если написать так
type
T1 = class(TObject)
  procedure Act; virtual;
end;
T2 = class(T1)
  procedure Act;overridde; end;
var
SomeObject: T1;
begin
SomeObject := T2.Create;
SomeObject.Act;  // calls T2.Act
end;

то будет щастье


 
Bless ©   (2005-02-02 16:09) [3]

REA[1]>
Компилятор знает, что SomeObject: T1 и вызывает метод T1.Act. Про метод T2.Act ему не известно в контексте этого объекта.

Как это ничего не известно? SomeObject.ClassType=T2.

icWasya ©  (02.02.05 15:24) [2]
то будет щастье


Это я и сам знаю. Только я не об этом спрашивал.


 
REA   (2005-02-02 16:52) [4]

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


 
Владислав ©   (2005-02-02 17:03) [5]

Судя по всему, Вам нужно познакомиться с разницей в вызовах виртуальных и невиртуальных методов.


 
Bless ©   (2005-02-02 17:48) [6]

Владислав ©  (02.02.05 17:03) [5]

Кстати, "Вы" - это черезчур :)


 
Bless ©   (2005-02-02 18:09) [7]

Вот блин, потерялся один пост.
Повторяю:

>Владислав ©  (02.02.05 17:03) [5]
Судя по всему, Вам нужно познакомиться с разницей в вызовах виртуальных и невиртуальных методов.

Это вряд ли (хотя чем черт не шутит). Ведь если поменять в посте [0]

T2 = class(T1)
 procedure Act;  // Act is redeclared, but not overridden
end;


на


T2 = class(T1)
 procedure Act; virtual; // Act is redeclared, but not overridden
end;


то результат останется тем же.


REA  (02.02.05 16:52) [4]
А на момент компиляции неизвестно, что попадет в эту переменную, поэтому компилятор не делает предположений относительно содержимого переменной, а вызывает метод по известному адресу.


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


 
Владислав ©   (2005-02-02 18:37) [8]

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

В точку. Просто в [4] некорректное утверждение.
Вот у тебя и вызывается виртуальный метод T1. Потому что в таблице именно он и есть. Если бы написал override, то там был бы метод T2.

Еще раз прочти [5].


 
Bless ©   (2005-02-03 09:10) [9]

>Еще раз прочти [5]

Зачем? Причем тут статические методы? Я же написал (и проверил, кстати), что если метод T2.act сделать виртуальным, то ничего не изменится.

>Вот у тебя и вызывается виртуальный метод T1. Потому что в
>таблице именно он и есть. Если бы написал override, то там был бы
>метод T2.

Так он и так там есть! Не в виртуальной таблице правда, поскольку он статический, но все-равно есть. И его тоже можно вызвать. Например, вот так: Т2(SomeObject).Act. Но почему сразу вызывается не он? Как компилятор рассуждает?

Для простоты переделаю исходный пример:

type
T1 = class(TObject)
 procedure Act; virtual;
end;
T2 = class(T1)
 procedure Act; VIRTUAL; //!!!!!!!!!!!!!
end;
var
SomeObject: T1;
begin
SomeObject := T2.Create;
SomeObject.Act;  // calls T1.Act
end;


Теперь в таблице виртуальных методов класса T2 присутствуют два метода Act (тоже проверил): один унаследованный и один свой. Почему в примере вызвается унаследованный?


 
Владислав ©   (2005-02-03 09:14) [10]

Знаешь, я больше повторяться не буду. Вот если после прочтения соответствующей документации у тебя появится желание продолжить тему, с удовольствием поучаствую.


 
REA   (2005-02-03 09:59) [11]

Это разные методы. Ты не заменил метод (override) в таблице, а добавил второй с тем же именем. По-хорошему надо бы блокировать такие попытки, но компилятор видимо надеется, что программист знает, что делает.



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2005.02.20;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.033 c
4-1103271326
pavel_guzhanov
2004-12-17 11:15
2005.02.20
Удаление директории на удаленном компе


9-1099913868
lifo
2004-11-08 14:37
2005.02.20
OpenGl


14-1106780098
VID
2005-01-27 01:54
2005.02.20
Токио (или Tokyo) - Индира Ганди.mp3


3-1106207417
АМБ
2005-01-20 10:50
2005.02.20
DBGrid. Работа скролинга.


14-1106885953
X9
2005-01-28 07:19
2005.02.20
Вопрос радиоэлектронщикам - ремонт "Кометы 225-1 Стерео"





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский