Форум: "Начинающим";
Текущий архив: 2012.01.08;
Скачать: [xml.tar.bz2];
ВнизМожно ли сравнивать типизированные указатели разных типов? Найти похожие ветки
← →
Очень злой (2011-09-28 22:06) [0]Возможно очень глупый вопрос, но на дельфи я несколько лет почти ничего не писал, поэтому сейчас почему-то не уверен на 100%.
Допустим:
var
a:TClass1;
b:TClass2;
насколько корректным будет сравнение типа:
if a<>b then ...
?
← →
Юрий Зотов © (2011-09-28 22:13) [1]Сравниваются адреса объектов a и b. Если это один и тот же объект, то будет FALSE, иначе - TRUE.
← →
Ega23 © (2011-09-28 22:14) [2]
> if a<>b then ...
Incompatible types будет.if @a<>@b then ...
илиif Pointer(a)<>Pointer(b) then ...
З.Ы. Сидел, курил, думал. Но практического применения такой конструкции так и не придумал. А зачем так делать?
← →
Юрий Зотов © (2011-09-28 22:21) [3]Привести к одному типу (Pointer, Cardinal и т.п.) - это само собой.
Но не так: if @a <> @b (поскольку это будет сравнение адресов переменных, а не самих объектов).
← →
Юрий Зотов © (2011-09-28 22:28) [4]
> А зачем так делать?
По-видимому, нужно сравнить "начинку" объектов, а не их адреса. В jav"е для этого предназначены методы equals и compareTo - но в своих класаах их, как правило, приходится перекрывать и писать сравнение ручками (что и естественно). Наверное, и здесь придется сделать примерно то же самое.
← →
Ega23 © (2011-09-28 22:28) [5]
> Но не так: if @a <> @b (поскольку это будет сравнение адресов
> переменных, а не самих объектов).
Да, чё-та ерунду сморозил.
← →
Ega23 © (2011-09-28 22:33) [6]
> Наверное, и здесь придется сделать примерно то же самое.
Ну в связи с новыми вкусностями RTTI, наверное можно и "начинку" сравнить без перекрытия по иерархии "CompareTo". Не уверен, правда, за strict private, а смотреть сейчас лениво.
← →
Очень злой (2011-09-28 22:40) [7]
> Юрий Зотов © (28.09.11 22:13) [1]
>
> Сравниваются адреса объектов a и b. Если это один и тот
> же объект, то будет FALSE, иначе - TRUE.
Собственно это мне и нужно. Нужно проверить или это не один и тот же объект.
← →
Очень злой (2011-09-28 22:44) [8]
>
> if Pointer(a)<>Pointer(b) then ...
думал что-то типа if a<>TClass1(b), но потом выяснилось, что на if a<>b then:
> > if a<>b then ...
>
>
> Incompatible types будет.
такого компилятор не выдает, а нормально проглатывает...
← →
Rouse_ © (2011-09-28 22:47) [9]
> Ega23 © (28.09.11 22:14) [2]
> if @a<>@b then ...
С завтрашнего дня будем плотно заниматься указателями и адресной арифметикой, чейт смотрю ну никак у тебя, вечно белое с холодным путаешь :)
← →
Ega23 © (2011-09-28 23:12) [10]
> такого компилятор не выдает
У меня выдаёт.
> Нужно проверить или это не один и тот же объект.
К Pointer приводи, так проще всего.
← →
oxffff © (2011-09-28 23:26) [11]
> насколько корректным будет сравнение типа:
>
> if a<>b then ...
>
> ?
Надо так
if not a.Equals(b) then
← →
Игорь Шевченко © (2011-09-28 23:42) [12]
> такого компилятор не выдает
надо сменить компилятор. ну или автора вопроса
← →
Очень злой (2011-09-28 23:50) [13]
> У меня выдаёт.
Хм. Проверил с другими типами. Действительно выдает.
Но в моем случае не выдает... Может потому что оба класса являются родственниками, т.е. один из них наследник наследника (типа внук) другого?
← →
Игорь Шевченко © (2011-09-29 00:30) [14]
> Может потому что оба класса являются родственниками, т.е.
> один из них наследник наследника (типа внук) другого?
партизан детектед
← →
DiamondShark © (2011-09-29 11:53) [15]
> Нужно проверить или это не один и тот же объект.
Если у тебя возникла такая задача, а TClass1 и TClass2 не являются предками/потомками друг друга, то у тебя серьёзные проблемы дизайна.
А если они родственники, то и проблемы со сравнением нет никакой.
← →
Cobalt © (2011-09-29 13:28) [16]Дык, по ID надо сравнивать!
← →
_Юрий (2011-09-29 18:13) [17]
> Если у тебя возникла такая задача, а TClass1 и TClass2 не
> являются предками/потомками друг друга, то у тебя серьёзные
> проблемы дизайна.
> А если они родственники, то и проблемы со сравнением нет
> никакой.
>
>
То есть лист из реализующих общий интерфейс неродственников - это проблема дизайна?
← →
Игорь Шевченко © (2011-09-29 18:33) [18]_Юрий (29.09.11 18:13) [17]
Если при этом требуется сравнение экземпляров классов то таки да, проблема дизайна
← →
_Юрий (2011-09-29 19:25) [19]
> Игорь Шевченко © (29.09.11 18:33) [18]
а как выкинуть объект из списка без сравнения указателей?
← →
oxffff © (2011-09-29 23:16) [20]
> DiamondShark © (29.09.11 11:53) [15]
>
> > Нужно проверить или это не один и тот же объект.
>
> Если у тебя возникла такая задача, а TClass1 и TClass2 не
> являются предками/потомками друг друга, то у тебя серьёзные
> проблемы дизайна.
Доказательства будут?
← →
oxffff © (2011-09-29 23:17) [21]
> Игорь Шевченко © (29.09.11 18:33) [18]
> _Юрий (29.09.11 18:13) [17]
>
> Если при этом требуется сравнение экземпляров классов то
> таки да, проблема дизайна
Доказательства будут?
← →
oxffff © (2011-09-29 23:25) [22]Если интересно, то можете почитать по теории типов про бинарные операции и рекурсивные типы.
← →
oxffff © (2011-09-29 23:30) [23]Вот пример такого сравнения, кстати он выявляет баг компилятора, а точнее правила отношения между типами неправильные, либо намеренно сделаны послабления для бинарных операторов для type parameter.
ISTuff=interface
procedure stuff;
end;
TA=class(TinterfacedObject,ISTuff)
procedure stuff;
end;
TB=class(TContainedObject,ISTuff)
procedure stuff;
end;
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure Check<T:class,ISTuff;U:class,ISTuff>(a:T;b:U);
end;
{ TB }
procedure TB.stuff;
begin
end;
{ TA }
procedure TA.stuff;
begin
end;
{ TForm1 }
procedure TForm1.Check<T, U>(a: T; b: U);
begin
if a=b then //<-баг здесь. Ошибку компилятор не показывает.
begin
a.stuff;
end
else
begin
a.stuff;
b.stuff;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var a:TA;
b:TB;
begin
//if a=b then <-ошибка компиляции
Check<TA,TB>(a,b);
end;
← →
Игорь Шевченко © (2011-09-30 00:05) [24]_Юрий (29.09.11 19:25) [19]
Было бы неплохо, если бы ты прочитал изначальный вопрос. "Сравнить указатели, чтобы выкинуть из списка" и "сравнить экземпляры, как у автора в вопросе", это слегка разные сравнения, нес па ?
← →
Германн © (2011-09-30 00:45) [25]
> Было бы неплохо, если бы ты прочитал изначальный вопрос.
А после изначального вопроса было и очень "смутное" уточнение"
> Нужно проверить или это не один и тот же объект.
Сам же говорил про "партизанов". :)
← →
_Юрий (2011-09-30 19:25) [26]
> Игорь Шевченко © (30.09.11 00:05) [24]
А совсем замечательно было бы, если бы и ты тоже его прочитал бы.
Вопрос был именно про сравнение указателей. Не веришь - прочитай название ветки. Или пост номер [7].
Что касается списка - это пример ситуации, когда может понадобиться такое сравнение. К вопросу о хорошем или плохом дизайне
← →
Игорь Шевченко © (2011-09-30 19:28) [27]_Юрий (30.09.11 19:25) [26]
Ты слово "типизированных" в названии ветки игнорируешь намеренно ?
← →
_Юрий (2011-09-30 20:33) [28]
> Игорь Шевченко © (30.09.11 19:28) [27]
var
instance: TClass1;
это и есть типизированный указатель.
Впрочем, по сабжу вы правы. Таки проблемы дизайна.
В противном случае лист будет состоять из TObject"ов, и получится, что сравниваемые - родственники.
← →
DiamondShark © (2011-09-30 23:05) [29]
> _Юрий (29.09.11 18:13) [17]
> То есть лист из реализующих общий интерфейс неродственников
> - это проблема дизайна?
Такой лист будет либо листом ТОбжектов (который родственник ВСЕХ объектов), либо листом интерфейсных ссылок.
Никаких сравнений неродственных объектов в реализации такого листа быть не может.
← →
DiamondShark © (2011-09-30 23:21) [30]
> oxffff © (29.09.11 23:16) [20]
> Доказательства будут?
Если нигде не применяются грязные хаки, вида:
b := TClass2(Pointer(a));
то переменные
var
a:TClass1;
b:TClass2;
заведомо никогда не получат одинаковых ссылок.
Очевидно же.
Если грязные хаки применяются, или возникли сомнения в заведомо ложном сравнении, то это называется проблемой дизайна.
Пинцет ваще. Ты бы ещё 2*2=4 попросил доказать.
← →
DiamondShark © (2011-09-30 23:22) [31]
> oxffff © (29.09.11 23:30) [23]
Это какой-то горячечный бред.
← →
oxffff © (2011-10-01 14:19) [32]
> DiamondShark © (30.09.11 23:21) [30]
То есть по твоему чисто технически, функции вида
procedure Check<T:class,ISTuff;U:class,ISTuff>(a:T;b:U);
и в которой нужно сравнить экземпляр типа T и U(причем никаких отношений между типом T и U не установлено) на идентичность в природе существовать не может?
← →
oxffff © (2011-10-01 14:26) [33]
> DiamondShark © (30.09.11 23:22) [31]
>
> > oxffff © (29.09.11 23:30) [23]
>
> Это какой-то горячечный бред.
Это пример решения задачи в общем виде, когда нужно сравнить экземпляры типов T и U, и которые реализуют интерфейс IStuff и в зависимости от этого
вызвать метод один или два раза.
Причем функции совершенно не важно в одном контейнере они хранятся или в разных.
← →
Cobalt © (2011-10-01 18:41) [34]Сравнивать яблоки с апельсинами - мсье знает толк в извращениях.
Однако можно сравнивать нечто общее между разными - например, у килограмма яблок и килограмма апельсин есть общее - вес. Его можно сравнить.
Однако, топикстартер партизанит :-)
Ну и пусть себе партизанит в одиночку.
← →
Очень злой (2011-10-01 22:08) [35]
> Однако, топикстартер партизанит :-)
Да не партизаню я. Вроде все давно выяснилось, а дискуссии (в всевозможных прочих направлениях) продолжаются.
А мне, как я писал нужно было сравнить являются ли 2 указателя ссылками на один и тот же объект. Просто разных типов они. Можно было бы привести к одному типу, но компилятор не стал ругаться на сравнение указателей разных типов. Вот поэтому и я задал вопрос. Хотя позже выяснилось что компилятор не ругается из-за того что типы (классы) родственники...
← →
oxffff © (2011-10-03 15:36) [36]
> Очень злой (01.10.11 22:08) [35]
>
> > Однако, топикстартер партизанит :-)
>
>
> Да не партизаню я. Вроде все давно выяснилось, а дискуссии
> (в всевозможных прочих направлениях) продолжаются.
Нет, никакой дискуссии. Сравнивать можно любые типы с любыми.
Просто есть поддержка со стороны RTL языка для определенных пар типов.
Еще есть перегрузка операторов.
Поэтому утверждающим о проблемах дизайна, я бы рекомендовал посмотреть для начала в зеркало.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2012.01.08;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.004 c