• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

[C++] Kolejność deklaracji w pliku nagłówkowym.

Object Storage Arubacloud
0 głosów
1,027 wizyt
pytanie zadane 6 lipca 2016 w C i C++ przez JAKUBW Nałogowiec (33,470 p.)

Witam,

Mam pytanie dotyczące kolejności deklarowania funkcji, klas itd. w pliku nagłówkowym. Jest jakaś globalna zasada deklaracji czy po prostu umowna? 

Obecnie pisałem tak:

  • #indef oraz #define
  • dyrektywy #include <>
  • dyrektywy #include ""
  • przestrzeń nazw (opcjonalnie)
  • dyrektywy #define
  • deklaracje zapowiadające funkcji globalnych
  • przestrzenie nazw
  • unie
  • typy wyliczeniowe enum
  • struktury
  • klasy
  • #endif

A po między każdym coś takiego:   

/** -------------------------------------------- **/

 Czy to jest prawidłowo?

2 odpowiedzi

+3 głosów
odpowiedź 6 lipca 2016 przez Sebastian Fojcik Nałogowiec (43,020 p.)
wybrane 6 lipca 2016 przez JAKUBW
 
Najlepsza

Oczywiście tak ściśle określona hierarchia nie występuje. Często to też zależy od znaczenia danego elementu. Czasami plik nagłówkowy jest dla klasy, a w nim dodatkowo umieszczasz mało znaczącą strukturę pomocniczą. Nie ma sensu jej umieszczać nad deklaracją klasy, bo to nie ona jest istotna. Nic jednak nie stoi na przeszkodzie, aby we własnych projektach trzymać się swojej stałej hierarchii, ale pozbawiasz się elastyczności.

Masz w rozpisce 2 razy przestrzenie nazw. Nie zgadzam się z tym, że przestrzeń powinna być za deklaracjami funkcji, bo to znaczy, że w deklaracji funkcji musiałbyś napisać, np. std::string, a później w pliku nagłówkowym już nie musisz tego std::. Trochę za bardzo namieszane. Przestrzenie nazw powinny być zaraz po dołączonych bibliotekach.

Podobnie jest z tym, że #define stoi po bibliotekach. Nie ma jednej reguły. Owszem, najczęściej właśnie tak będzie, ale weźmy prosty przykład. Biblioteka <cmath> udostępnia stałe matematyczne takie jak PI. Rzecz w tym, że aby z nich skorzystać (w Visual Studio) musisz przed dołączeniem biblioteki <cmath> umieścić makro:
#define _USE_MATH_DEFINES_
Deklarujesz chęć używania stałych w ten sposób. Zapis wygląda tak:

#define _USE_MATH_DEFINES_
#include <cmath>
// ... reszta ...

Jestem również absolutnym przeciwnikiem pisania

/** -------------------------------------------- **/

Z bardzo prostej przyczyny. Jeśli chciałbyś z jakiegoś powodu wykomentować część kodu, w której jest taki "separator kodu", to nie dasz rady tego zrobić, bo tych komentarzy nie można zagnieżdżać. Musiałbyś użyć komentarzy // i prawda, środowiska udostępniają masowe komentowanie kodu, ale to nie na tym polega, aby utrudniać sobie życie. Dobry programista znajdzie deklarację klasy bez takich liniowych przeszkadzajek.

Stosowanie się do jakichś reguł, które będziesz stosował z powodzeniem w swoich projektach jest oczywiście dobre, ale nie przywiązywałbym do tego tak wielkiej wagi. Po prostu jeśli coś jest ważniejsze to idzie na górę. Tak powinny być konstruowane pliki nagłówkowe.

Jeśli chodzi o strukturę plików nagłówkowych to na pewno należy dołączać biblioteki w jednym miejscu, przestrzenie deklarować w jednym miejscu i funkcje również. Choć na chłopski rozum. Kto w pliku nagłówkowym deklaruje klasy wraz z funkcjami globalnymi? Każda klasa powinna mieć swój własny plik nagłówkowy, a nie dzielić go z jakimiś funkcjami. Jeśli są to funkcje, które operują na obiektach danej klasy, to czemu nie zrobić je statycznymi?
Takie rozwiązanie jest w C# z całą biblioteką matematyczną. W C++ funkcje potęgujące, pierwiastkujące itd. są globalne (bo biblioteka <cmath> pochodzi z C), a w C# wszystkie są statyczne. Da się więc żyć.

Czuję, że pomimo tego wszystkiego co napisałem, to nie udzieliłem żadnej odpowiedzi. Hmm... może dlatego, że takowej nie ma. Nikt nie może wskazać jednej hierarchii. To zależy od Ciebie. Pisz aby było ładnie i wygodniej i nie utrudniaj sobie życia trzymając się ściśle własnych zasad. Jesteśmy programistami, poetami piszącymi wspaniałymi językami. Kod ma być piękny, a nie zgodny z konwencją w 100%.

Pozdrawiam.

komentarz 6 lipca 2016 przez JAKUBW Nałogowiec (33,470 p.)

Te 2 przestrzenie nazw to chodziło mi, że to pierwsze to using namespace a drugie definicje własnych przestrzeni nazw.

A co do deklaracji globalnych funkcji to na przykład funkcje do konwersji int do string. Dzięki temu mam ją zawsze i wszędzie w programie.

A z tymi komentarzami a prawda jednak, co prawda gdy dziele na wiele plików (a często tak robię) i tylko jedna klasa to nie dodaje komentarzy. Od dzisiaj robię tak:

/// ************************************ //

Dziękuję za odpowiedź. Pozdrawiam.

komentarz 6 lipca 2016 przez Sebastian Fojcik Nałogowiec (43,020 p.)
edycja 6 lipca 2016 przez Sebastian Fojcik

Rozumiem już o co chodziło z przestrzeniami.

Jeśli chodzi o takie funkcje konwertujące, to ja robię to tak, że tworzę plik nagłówkowy ze wszystkimi funkcjami pomocniczymi. Często nazywam ją "components.h" albo "extension.h" (ang. rozszerzenie, dobudowanie). I dołączam ją... wszędzie. Czasami tworzę do niej własną przestrzeń nazw. Głównie chodzi o to, że to jest moje własne rozbudowanie funkcji standardowych.

Aczkolwiek w twoim przypadku konwersja z int do string jest funkcją standardową i zwie się:
to_string( int );
http://www.cplusplus.com/reference/string/to_string/
Jest to funkcja dodana w C++11. Upewnij się, że piszesz w tym standardzie.

Podobnie z konwersją string do int, funkcja: stoi( string ). "stoi" czyli właśnie string to int.
http://www.cplusplus.com/reference/string/stoi/
Jeśli takich funkcji nie masz (bo nie piszesz w C++11), to zawsze możesz posłużyć się strumieniami (konwersja za pomocą strumieni jest prosta i intuicyjna, zawsze chętnie ktoś Ci pokaże jak to się robi)

Jeśli chodzi o komentarze, to dobry wybór. Przyznam Ci się (ale ćśśśś), że sam lubię wstawić takie separatory, ale u mnie wyglądają tak:

// ------------- FUNKCJE POMOCNICZE ------------- 

Wygląda to ładnie, schludnie i nazywa "rozdział" kodu. Oczywiście oficjalnie jestem przeciw takim "ozdobom", więc ćśśśś ;-)

0 głosów
odpowiedź 6 lipca 2016 przez C☺ndzi Stary wyjadacz (12,100 p.)
Raczej każdy robi tak jak mu wygodnie. Polecam trzymać się jednego stylu (na przykład prywatne pola (zmienne) klasy pisać jako m_nazwa).

Podobne pytania

0 głosów
1 odpowiedź 379 wizyt
pytanie zadane 5 sierpnia 2016 w C i C++ przez Damian11131 Stary wyjadacz (13,490 p.)
0 głosów
1 odpowiedź 112 wizyt
pytanie zadane 24 października 2016 w C i C++ przez Beksio Początkujący (260 p.)
0 głosów
3 odpowiedzi 227 wizyt
pytanie zadane 11 lipca 2016 w C i C++ przez SebekChlebek Stary wyjadacz (11,290 p.)

92,576 zapytań

141,426 odpowiedzi

319,651 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...