To makro można zdefiniować w nagłówku globalnym lub lepiej jako parametr wiersza polecenia kompilatora:
#define me (*this)
I przykład użycia:
some_header.h:
inline void Update()
{
/* ... */
}
main.cpp:
#include "some_header.h"
class A {
public:
void SetX(int x)
{
me.x = x;
me.Update();
}
void SomeOtherFunction()
{
::Update();
}
/*
100 or more lines
...
*/
void Update()
{
// ...
}
int x;
};
Tak więc w metodzie klasowej, kiedy uzyskuję dostęp do członka klasy, zawsze używam me
, a podczas uzyskiwania dostępu do identyfikatora globalnego zawsze używam ::
. To daje czytelnikowi, który nie jest zaznajomiony z kodem (prawdopodobnie po kilku miesiącach) zlokalizowane informacje o tym, do czego można uzyskać dostęp bez konieczności szukania gdzie indziej. Chcę zdefiniować, me
ponieważ uważam, że używanie this->
wszędzie jest zbyt głośne i brzydkie. Ale czy można #define me (*this)
to uznać za dobrą praktykę w C ++? Czy są jakieś praktyczne problemy z me
makrem? A jeśli jako programista C ++ będziesz czytał jakiś kod za pomocą me
makra, chciałbyś go, czy nie?
Edycja: Ponieważ wiele osób twierdzi, że nie przeciwstawia się temu me
, ale ogólnie przeciwstawia się temu wyraźnie. Myślę, że może nie być jasne, jakie są korzyści z „wyraźnego wyrażenia tego wszędzie”.
Jakie są korzyści z „wyrażania tego wszędzie”?
- Jako czytelnik kodu masz pewność, co jest dostępne i możesz skoncentrować się na innych rzeczach niż zweryfikować - w jakimś odległym kodzie - czy naprawdę można uzyskać dostęp do tego, co według ciebie jest dostępne.
- Możesz użyć funkcji wyszukiwania bardziej szczegółowo. Wyszukiwanie „
this->x
” może dać więcej pożądanych wyników niż tylko wyszukiwanie „x
” - Kiedy usuwasz lub zmieniasz nazwę jakiegoś członka, kompilator niezawodnie powiadamia cię w miejscach, w których ten członek jest używany. (Niektóre funkcje globalne mogą mieć tę samą nazwę i istnieć szansa, że możesz wprowadzić błąd, jeśli nie używasz tego jawnie).
- Kiedy refaktoryzujesz kod i czynisz funkcję inną niż element członkowską (aby uzyskać lepszą enkapsulację) jawnie, pokazuje to miejsce, które musisz edytować i możesz łatwo zastąpić to wskaźnikiem do instancji klasy podanej jako parametr funkcji niebędącej członkiem
- Zasadniczo, gdy zmieniasz kod, istnieje więcej możliwości wystąpienia błędów, gdy nie używasz tego jawnie, niż gdy używasz tego jawnie wszędzie.
- Wyraźnie to jest mniej głośne niż wyraźne „m_”, gdy uzyskujesz dostęp do członka z zewnątrz (
object.member
vsobject.m_member
) (dzięki @Kaz zauważył ten punkt) - Wyjaśnij, że rozwiązuje to problem uniwersalnie dla wszystkich członków - atrybutów i metod, podczas gdy „m_” lub inny prefiks jest praktycznie użyteczny tylko dla atrybutów.
Chciałbym dopracować i rozszerzyć tę listę, powiedzieć mi, czy wiesz o innych zaletach, i użyć przypadków, aby to wszędzie wyrazić .
#define self (*this)
? Możesz nawet mieszać oba makra i mieć niektóre pliki imitujące VB i inne Python. :)#include "vb.h"
,#Include pascal.h
albo#include FOTRAN.h
i mieć kolejną osobę dotknąć kod przedkłada go TDWTF .me_x
.Odpowiedzi:
Nie, nie jest.
Zwróć uwagę na programistę, który będzie utrzymywał Twój kod za kilka lat, długo po tym, jak wyszedłeś na bardziej zielone pastwiska i postępuj zgodnie z powszechnymi konwencjami języka, którego używasz. W C ++ prawie nigdy nie musisz pisać
this
, ponieważ klasa jest zawarta w kolejności rozpoznawania symboli, a gdy symbol zostanie znaleziony w zakresie klasy,this->
jest to implikowane. Więc nie pisz tego tak, jak wszyscy.Jeśli często się mylisz, które symbole pochodzą z zakresu klasy, zwykle stosuje się wspólny wzorzec nazewnictwa dla członków (pola i czasami metody prywatne; nie widziałem, aby był używany do metod publicznych). Najczęstsze z nich obejmują sufiks
_
lub prefiks za pomocąm_
lubm
.źródło
this
aby wyraźnie zaznaczyć, że zmienna nie jest lokalna dla metody. Pytanie dotyczy tego, czy makrome
powinno istnieć, a nie, czythis
należy tego użyć.me.
zamiastthis->
. Ponieważ nie ma takiej potrzeby,this->
nie ma takiej potrzeby,me.
a zatem nie ma potrzeby makra.this->
„jest konieczne”. W rzeczywistości PO twierdzi, że używa,this->
mimo że nie jest to konieczne. Pytanie dotyczy tego, czyme.
należy użyć zamiast tegothis->
, na co ta odpowiedź w rzeczywistości nie odpowiada.this
dlatego też dyskusja na ten temat jest wymagana, aby osiągnąć w pełni zrównoważony wniosek.Więc chcesz stworzyć nowy język. Następnie zrób to i nie kalekuj C ++.
Istnieje kilka powodów, aby tego nie robić:
this
jest, a dodając takie makro, w rzeczywistości dodajesz nowe słowo kluczowe. Co jeśli wszyscy przedstawią coś, co lubią? Jak wyglądałby kod?(*this).
anithis->
wcale, z wyjątkiem niektórych szczególnych przypadków (zobacz tę odpowiedź i wyszukaj „to->”)Twój kod nie różni się od
#define R return
, który widziałem w rzeczywistym kodzie. Powód? Mniej pisania!Przechodzę nieco poza tematem, ale tutaj zamierzam rozwinąć punkt 3 (nie używaj
(*this).
anithis->
na zajęciach).Po pierwsze,
(*this).
czythis->
są wykorzystywane do zmiennych składowych dostępu lub funkcji obiektu. Korzystanie z niego jest bez znaczenia i oznacza więcej pisania. Ponadto czytanie takiego kodu jest trudniejsze, ponieważ jest więcej tekstu. To oznacza trudniejszą konserwację.Więc jakie są przypadki, w których musisz użyć
this->
?(a) Niefortunny wybór nazwy argumentu.
W tym przykładzie
this->
jest wymagany, ponieważ argument ma taką samą nazwę jak zmienna elementu:(b) W przypadku szablonów i dziedziczenia (patrz to )
W tym przykładzie kompilacja nie powiedzie się, ponieważ kompilator nie wie, do której zmiennej
v
należy uzyskać dostęp.źródło
*this.
ithis->
this->
jest równie użyteczny jakauto
w wersji wcześniejszej niż c ++ 11. Innymi słowy, po prostu zwiększa szum kodu.Radzę tego nie robić. To daje czytelnikowi, który nie zna Twojego makra, duży „ WTF ”, gdy tylko to zobaczy. Kod nie staje się bardziej czytelny przy wymyślaniu „nowych konwencji” w stosunku do ogólnie przyjętych bez rzeczywistej potrzeby.
Może ci się to wydawać, być może dlatego, że dużo programowałeś w językach przy użyciu słowa kluczowego
me
(chyba Visual Basic?). Ale tak naprawdę to tylko kwestia przyzwyczajenia się do tego -this->
jest dość krótka i myślę, że większość doświadczonych programistów C ++ nie zgodzi się z twoją opinią. A w powyższym przypadku ani użycie,this->
ani użycie nieme
jest właściwe - najmniejszy bałagan, pozostawiając te słowa kluczowe poza dostępem do członków danych wewnątrz funkcji członka.Jeśli chcesz, aby twoje prywatne zmienne składowe były odróżniane od lokalnych, dodaj coś link
m_
jako przedrostek lub podkreślnik jako przyrostek (ale jak widać tutaj , nawet ta konwencja jest „zbyt głośna” dla wielu osób).źródło
_
powinien być przyrostek ; jako przedrostek jest zarezerwowany dla wewnętrznych symboli standardowych bibliotek i rozszerzeń dostawcy.__
(dwa podkreślenia) lub podkreślenia, po których następuje duża litera. Pojedynczy znak podkreślenia, po którym następuje mała litera, jest w porządku, o ile nie znajduje się w globalnej przestrzeni nazw.Proszę nie rób tego! Próbuję poradzić sobie z dużą bazą kodu, gdzie makra są wszędzie, aby zaoszczędzić pisania. Złą rzeczą w przedefiniowaniu tego dla mnie jest to, że preprocesor zastąpi go wszędzie, nawet jeśli nie jest to objęte zakresem / nie ma zastosowania, na przykład samodzielna funkcja, twój kolega z pracy może mieć lokalną zmienną o nazwie mnie gdzie indziej .. (s) nie będzie szczęśliwy debugowania ... W końcu masz makra, których nie możesz używać we wszystkich zakresach.
źródło
NIE!
Wyobraź sobie zamieszanie, które wystąpi, jeśli ktoś # dołącza ten nagłówek, nie znając twojej sztuczki, a gdzie indziej w swoim pliku mają zmienną lub funkcję o nazwie „ja”. Byliby okropnie zdezorientowani tym, co wydrukowałoby nieprzenikniony komunikat o błędzie.
źródło