Styl akcesorówPonieważ w C++ nie ma mechanizmu właściwości, do kontroli dostępu do pól w klasie wykorzystuje się metody dostępowe, czyli akcesory. Od kiedy zajmuję się programowaniem w tym języku, starałem się wynaleźć jakąś sensowną konwencję odnośnie tego, w jakiej postaci metody te zapisywać i jak je nazywać.
Niektórzy preferują na przykład utworzenie tylko jednej funkcji postaci:
która ustawia nową wartość pola i jednocześnie zwraca nam poprzednią. Takie rozwiązania realizuje chociażby funkcja set_new_handler, ustawiająca procedurę obsługi błędu braku pamięci dla operatora new. Nie akceptuję tego sposobu z jednego prostego powodu: bardzo częsta operacja pobrania wartości wymaga tutaj aż dwóch wywołań, które wyglądają co najmniej dziwnie.
Akcesory muszą więc być dwa (get/set). Pozostaje wtedy kwestia: jak je nazywać? Tutaj doszedłem do trzech możliwości:
X. Dla kompilatora będą one z łatwością odróżnialne, jako że getter jest bezparametrowy, a setter oczywiście nie.GetX i SetX.SetX, ale getter po prostu X.Chyba każdy z tych trzech sposobów widziałem w użyciu w jakiejś popularnej bibliotece, więc nie są to tylko teoretyczne propozycje. Sam zresztą wypróbowałem po kolei każdą z nich.
I tak rozwiązanie pierwsze jest na pewno najkrótsze, ale sprawia, że wywołania setterów wyglądają dziwnie. Widząc:
można zastanawiać się, co autor miał na myśli, a interpretacja "ustaw obiekt kamery dla sceny" nie musi być wcale tą, która nasuwa się jako pierwsza.
Z kolei drugi sposób (z Get/Set) jest całkowicie jednoznaczny, lecz w zamian potrafi wyprodukować łańcuszki w rodzaju poniższego:
Wszystkie te Gety trudno uznać za potrzebne do szczęścia, chociaż javowcy pewnie by się kłócili ;)
Dlatego też sposób trzeci polega na pozbyciu się ich (Getów, nie koderów Javy :>). Tę właśnie konwencję (SetX/X) wykorzystuję obecnie i jak dotąd stwierdzam, że sprawdza się dobrze. Dla ostatecznych wniosków byłby jednak potrzebny dłuższy okres, by przekonać się, czy po upływie pewnego czasu nadal mogę patrzeć na swój kod z zachowaniem równowagi psychicznej ;]
Mysle, ze wybrales srednio dobra droge :) Get/Set jest jak najbardziej poprawne i doskonale ulatwia czytanie kodu. Co do nazewnictwa funkcji i ogolnie porzadku w kodzie polecam lekture "Clean Code" Roberta C. Martina.
Swego czasu próbowałem zasymulować akcesory makrami, wyglądało to tak:
//...
int param_x;
Accesor ToParamX
{
set
{
cout <<"Accesor set" <<endl;
param_x = value;
}
get
{
cout <<"Accesor get" <<endl;
return param_x;
}
};
ToParamX ParamX;
Ale nie pamiętam jak się to skończyło, czy nie działało(najprawdopodobniej), czy po prostu zdecydowałem że to mi zasyfi kod za bardzo, w każdym razie teraz używam rozwiązania 1.
Tak, jak teraz przejrzałem ten kod to okazuje się że to jednak nie działało... ale szperając po dysku znalazłem plik z rozwiązaniem działającym: Link. Ale jak widać jest to zbyt śmieciaste rozwiązanie, więc można to traktować tylko jako ciekawostkę, czy proof of concept że accesory(właściwości) w c++ są możliwe jak się człowiek uprze ^^
polymorph: Na coś podobnego (do tego rozwiązania z linku) wpadłem już jakiś czas temu, ale nie pomyślałem o użyciu boost::bind przez co rzecz nie była nawet teoretycznie używalna (wymagałaby drugiego parametru w szablonie: typu klasy, w której zawarty jest akcesor).
To, co pokazałeś, jest zdecydowanie lepsze - właściwie to już jest niemal to samo, co properties z Delphi (po niezbyt trudno uzupełnieniu o drugi szablon, ReadOnlyAccessor).
Jest jeszcze notacja put_X i get_X, stosowana w klasach COM AFAIR.
Ja stosuję nazwy GetX i SetX. Jest taka zasada, która mówi, że nazwy metod powinny mieć czasownik jako że są to operacje, tak jak nazwy pól rzeczownik.
Znaki nowej linii dodawane są automatycznie.
Do wstawiania kodu użyj [code][/code], a do wzorów (w LaTeX-u) [tex][/tex].
Dozwolne tagi HTML:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>