Ostrożnie z nazwami

W ramach jednej z bibliotek zaimplementowaliśmy klasę o nazwie CTime, obsługującą najprzeróżniejsze operacje na dacie i czasie (od reprezentowania dowolnej daty, także spoza przedziału 1.I.1970 - któryś tam dzień 2037, przez rozmaite operacje arytmetyczne, po konwersje do dziwnych nieraz reprezentacji typu kilka różnych dni juliańskich). Klasa działała jak trzeba i była obszernie używana na różnych platformach (także w programach konsolowych kompilowanych Visual C++).

Któregoś pięknego dnia pojawiła się potrzeba przygotowania prostego interfejsu użytkownika z wykorzystaniem MFC. I okazało się, że MFC zawiera własną klasę CTime a w czasie kompilacji mamy konflikt. Oczywistym odruchem byłaby zmiana nazwy naszej klasy, tyle, że była ona już używana w kilkuset plikach źródłowych.

Ostatecznie poradziliśmy sobie zmieniając nazwę klasy i dostarczając - warunkowo, tylko gdy kompilacja nie obejmowała MFC - typedef z nowej nazwy na starą. Ale trudno uznać to za rozwiązanie eleganckie.

Problemów takich trudno uniknąć - bo trudno przewidzieć z jaką zewnętrzną biblioteką możemy się musieć linkować a konflikt może wystąpić nawet poza naszym kodem (znam przypadek poważnych problemów wynikających z konfliktu nazw jakiejś funkcji z biblioteki C++ Buildera z funkcją dostarczaną w ramach pewnej biblioteki telekomunikacyjnej). Niemniej jednak, tam gdzie to możliwe, warto problemów unikać.

Częściowym obejściem problemu może być przyjęcie jak najbardziej specyficznych standardów nazewniczych, wrzucanie nazwy firmy jako prefiksu nazw klas i funkcji itp - ale jest to uciążliwe i nieeleganckie.

Dobrym rozwiązaniem jest wykorzystanie namespace - tyle, że ten mechanizm jest młodszy niż wiele "naszych" programów i bibliotek, w których trzeba by go wstecznie wprowadzać. Ale obecnie obsługują go już chyba wszystkie istotne kompilatory - i warto rozważyć taką adaptację kodu.

komentarze obsługiwane przez Disqus