Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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.005 c
1-1279098114
packpaul
2010-07-14 13:01
2012.01.08
Реализация null-методов класса в Delphi


11-1240200030
Дмитрий
2009-04-20 08:00
2012.01.08
Обработка исключений


2-1316525951
istok20
2011-09-20 17:39
2012.01.08
посоветуйте компонент для галереи...


2-1317637088
onyx2012
2011-10-03 14:18
2012.01.08
кастомная сортировка в ExpressQuantumGrid


15-1316723402
Юрий
2011-09-23 00:30
2012.01.08
С днем рождения ! 23 сентября 2011 пятница





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский