Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2012.01.08;
Скачать: CL | DM;

Вниз

Можно ли сравнивать типизированные указатели разных типов?   Найти похожие ветки 

 
Очень злой   (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;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.01 c
15-1316444919
stas
2011-09-19 19:08
2012.01.08
Геометрия.Луч.


2-1317192067
Alex_C
2011-09-28 10:41
2012.01.08
ValueListEditor - вид 3D как в Object Inspector


15-1316692399
Очень Злой
2011-09-22 15:53
2012.01.08
помогите найти заразу


6-1249301566
BreakPoint
2009-08-03 16:12
2012.01.08
Какой процесс слушает сокет?


2-1310979425
D_2010
2011-07-18 12:57
2012.01.08
Как обработать приход нескольких одинаковых TMessage как одно?