Stałe w Objective-C, C a C++

Zauwazylem, ze czesc moich znajomych programistow nie jest przekonana, co do sposobu prawidlowego definiowania stanych w Objective-C. Wiekszosc osob uznaje wyzszosc uzycia stalych w stosunku do makra #define. Jednak sam sposob deklaracji stalej budzi watpliwosci.

W przypadku stalych, ktore maja byc widoczne w wielu plikach .m, sytuacja jest prosta – deklarujemy stale w pliku .h, wykorzystujac slowo kluczowe ‚extern’. W pliku implementacji .m przypisujemy im wartosc:

// Const.h
extern const int constantAccessibleFromMultipleFiles;

// Const.m
const int constantAccessibleFromMultipleFiles = 55;

W przypadku definiowania literalu, kod bedzie wygladal podobnie:

// LiteralConst.h
extern NSString *const literalConstant;

// LiteralConst.m
NSString *const literalConstant = @"I haz code";

NSString *const oznacza staly wskaznik na napis, NSString const* byloby z kolei wskaznikiem na stala (mozna przypisac do niego inna stala w trakcie wykonania programu).

Jakie zastosowac podejscie, kiedy chcemy, aby stala widoczna byla tylko w jednym pliku? Deklarujemy ja na poczatku pliku impementacji *m. Ale w jaki sposob?

Mamy dwie mozliwosci:

// ImplementationFileConstOne.m
NSString *const implementationFileConstOne = @"one";

albo:

// ImplementationFileConstTwo.m
static NSString *const implementationFileConstTwo = @"two";

Prawidlowa jest opcja druga. Czesc osob nie jest jednak przekonana i czesto pomija slowo kluczowe ‚static’ przy deklaracjach stalych w plikach .m. Czy ten blad ma jakies uzasadnienie?

Otoz ma. W jezyku C++ nie ma roznicy pomiedzy stala deklarowana przy uzyciu slowa kluczowego ‚static’ oraz bez niego. Bardziej precyzyjnie: w C++ stale globalne sa domyslnie statyczne. Oznacza to, ze linkowanie jest ograniczone do jednej jednostki translacji (jednego pliku cpp, ‚internal linkage’).

 
// OffsetConsts.cpp
const int offset = 20;

// OffsetConstsEquivalent.cpp
static const int offset = 20;

Oznacza to rowniez, ze w C++ nawet bez uzycia slowa kluczowego ‚static’, mozliwe jest deklarowanie stalych o identycznych nazwach (w roznych plikach .cpp). Nawet jesli przypiszemy do nich inne wartosci, nie spowoduje to bledu linkowania.

// ConstantsFileOne.cpp
const int offset = 10;

// ConstantsFileTwo.cpp
const int offset = 30;

W jezyku C jednak zachowanie jest inne. Stale globalne nie sa domyslnie statyczne. Proba zdefiniowania niestatycznych stalych w wielu plikach .c, spowoduje blad linkowania. Rozwiazaniem jest definiowanie stalych jako statyczne w plikach .c:

// ConstantsInCFileOne.c
static const int offset = 10

// ConstantsInCFileTwo.c
static const int offset = 30;

Powyzszy przyklad zostanie zlinkowany bez bledow.

Jak wyglada sytuacja w Objective-C? Jezyk ten jest rozszerzeniem C, maja zatem zastosowanie takie same zasady. Stala zdefiniowana bez uzycia slowa ‚static’ bedzie miala inny zakres linkowania, niz stala statyczna. Jesli w kilku roznych plikach zdefiniujemy stale o identycznej nazwie i zapomnimy dodac slowko kluczowe ‚static’, otrzymamy w rezultacie blad linkera.

Warto wiec zapamietac, ze stale definiowane w plikach implementacji w Objective-C nalezy poprzedzac keywordem ‚static’, natomiast w C++ nie jest to konieczne.

Reklamy
2 comments
  1. Xion said:

    Ad. trzeci przykład: nie można po prostu zdefiniować stałej w pliku .m bez static? (Zakładam że .m w ObjC to odpowiedniki .c/.cc z C/C++)

  2. Wyszo said:

    Upps… W przykladzie z plikami .m byl blad w rozszerzeniu – chodzilo o pliki .m a nie pliki.h, dzieki Tobie poprawilem, thx! Wystepuje tez mala frywolnosc w uzywaniu terminow ‚definiowanie’ i ‚deklarowanie’, ale na razie musi zostac.

    Generalnie nie powinno sie – w przeciwienstwie do C++, jesli nie dasz static przed stala, dostaniesz external linkage. Dlatego w cpp nikt nie bedzie uzywal static constow, a w Obj-C jest to dobra praktyka.

    Natomiast w plikach .m wewnatrz metod, const i static const uzywamy tak samo jak w C++, zaleznie od tego o co nam chodzi.

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Wyloguj / Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Wyloguj / Zmień )

Zdjęcie na Facebooku

Komentujesz korzystając z konta Facebook. Wyloguj / Zmień )

Zdjęcie na Google+

Komentujesz korzystając z konta Google+. Wyloguj / Zmień )

Connecting to %s

%d blogerów lubi to: