2010-01-19 10 views
11

Zawsze się nad tym zastanawiałem, ale dlaczego przeciążanie operatorów nie jest dostępne na lekcjach w Delphi?Dlaczego dla klas w Delphi nie jest dostępne przeciążanie operatorów?

Pamiętam, jak czytałem odpowiedź raz w biegu, i powiedziałem, że to będzie w konflikcie z czymś, ale nie pamiętam wiele. O ile mogę powiedzieć, tylko niejawny operator może powodować trochę problemów, ponieważ klasy są przechowywane na stercie, a przypisywanie jest w rzeczywistości kopią adresu sterty (w zasadzie kopiowanie wskaźników).

+1

Działa w Delphi.Net ponieważ .NET robi zbierania śmieci. Można to rozwiązać w rodzimym języku Delphi na dwa sposoby: 1. jeśli operatory były dozwolone na interfejsach, a klasy implementujące ten operator dziedziczą z TInterfacedObject. 2. Jeśli klasy zarządzające zostały dodane do języka Delphi. W tej chwili Mason ma rację: dostaniesz wszędzie wycieki pamięci. Zobacz także mój referat na ten link: http://wiert.wordpress.com/2009/10/19/delphi-operator-overloading-table-of-operators-names-and-some-notes-on-usage-and -glitches/ –

+0

Tak, rozumiem, dlaczego można to uznać za problem, i to jest dokładnie to, co przeczytałem w tym artykule, teraz, gdy go pamiętam. Jednakże, jak powiedziałem w swoim komentarzu do odpowiedzi Masona, nie sądzę, że jest to ograniczenie, ponieważ myślę, że możesz to zrobić, jeśli zaimplementujesz tylko niewielką garbage collection (która nie będzie miała żadnych skutków ubocznych). – Cloud737

+0

Jeśli intefaces miałoby operatorów, pojawiłoby się wiele problemów, jak na przykład brak możliwości anulowania niektórych operatorów. Na przykład, wyobraź sobie posiadanie operatora Implicit w interfejsie, a następnie posiadanie obiektu, który potrzebuje interfejsu, ale absolutnie nie jest także operatorem Implicit. Kiedy spróbujesz zadania, całe piekło może się wyrwać i trudno będzie znaleźć twój problem. Rzecz w tym, że operatorzy nie powinni być nigdy dziedziczeni, jeśli chcesz użyć "odziedziczonej" wersji, powinieneś przeładować ją ponownie, a następnie typecast. Ale to oznacza, że ​​klasy również muszą je mieć. – Cloud737

Odpowiedz

9

Zamknij. Dzieje się tak dlatego, że obiekty są typami referencyjnymi, a pamięć jest zarządzana ręcznie. Więc jeśli powiesz myResult := myObject1 + myObject2 + myObject3;, będziesz musiał stworzyć gdzieś tam obiekt pośredni i nie ma kodu, który by go zwolnił, więc dostaniesz wycieków pamięci.

+1

Kompilatory mogą dodaj kod do zarządzania ciągami, dlaczego więc nie może obsłużyć ukrytego obiektu? Nie sądzę, że to jest powód. – mj2008

+0

@ mj2008: Po pierwsze, łańcuchy nie mają i nie mogą mieć niestandardowych konstruktorów.Obiekty pośrednie w tym przypadku mogą być nieważne, jeśli nie zostaną utworzone za pomocą odpowiedniego konstruktora z odpowiednimi parametrami, których kompilacja nie zawsze/zawsze będzie w stanie określić. Ograniczenia, które musiałyby zostać nałożone na klasy w celu wsparcia przeciążania operatorów, wydawałoby mi się, że przewyższają korzyści. A ponieważ możesz teraz mieć "rekordy z metodami", możesz użyć przeciążenia operatora w połączeniu z tymi, jeśli chcesz. – Deltics

+0

Widzę, dlaczego na pierwszy rzut oka to nie zadziałałoby. Jednak czy kompilator nie może automatycznie zniszczyć obiektów pośredniczących, z wyjątkiem ostatniego w tym przypadku, a następnie traktować zadanie jako normalne? Na przykład najpierw utwórz myIntermediaryObject1 jako wynik (myObject1 + myObject2), a następnie dodaj go za pomocą myObject3, tworząc myIntermediaryObject2, automatycznie niszcząc myIntermediaryObject1 i wykonując zadanie jak zwykle? W końcu to programista ma obowiązek dbać o cofnięcie przypisania myResult, jeśli to konieczne, a kompilator może zająć się resztą tymczasowych obiektów. – Cloud737

0

Mason Wheeler mówi, że to niemożliwe, ponieważ zarządzanie obiektami pośrednimi.

Ale według dokumentacji Embarcadero, operatorów klasy gdzie jest to możliwe z Delphi 2009.

RAD Studio 2009 - Operator Overloading New Delphi language features since Delphi 7

+0

Przeciążenie operatora dotyczy rekordów. Rekordy są typami wartości, podczas gdy klasy są typami odniesienia. Dokumentacja w twoich linkach jest błędna (chociaż stwierdzają, że ta funkcja dotyczy rekordów, ale kończy się niepowodzeniem, używając klas w przykładach). Zobacz ['Przeciążenie operatora XE3'] (http://docwiki.embarcadero.com/RADStudio/XE3/en/Operator_Overloading_ (Delphi)). –

+0

Jest dozwolone tylko w rekordach, a nie w klasach. Ale teraz z XE rekordy mogą mieć metody i właściwości. Więc ... – PSyLoCKe

+1

@All Dokumenty są takie, jakimi są, ponieważ kompilator .net obsługuje przeciążanie nad klasami. Możliwe z powodu GC. –

Powiązane problemy