Zawsze miałem wątpliwości co do plików nagłówkowych. Są tak dziwne: dołączasz plik .h, który nie zawiera .cpp, ale .cpp też jest jakoś skompilowany.
Ostatnio dołączyłem do projektu zespołowego i oczywiście używane są zarówno pliki .h, jak i .cpp.
Rozumiem, że jest to bardzo ważne, ale nie mogę żyć z kopiowaniem i wklejaniem każdej deklaracji funkcji w każdej z wielu klas, które mamy.
Jak skutecznie obsługiwać konwencję 2-plików?
Czy są jakieś narzędzia, które mogą w tym pomóc, lub automatycznie zmienić jeden plik, który wygląda jak przykład poniżej, na .h i .cpp? (specjalnie dla MS VC ++ 2010)
class A
{
...
Type f(Type a,Type b)
{
//implementation here, not in another file!
}
...
};
Type f(Type a)
{
//implementation here
}
...
c++
language-design
naming
Oleh Prypin
źródło
źródło
Odpowiedzi:
Pisanie bardziej przyjazne dla refaktoryzacji C ++
W C ++ nie musisz wcale używać nagłówków. Możesz zdefiniować cały obiekt w jednym pliku, tak jak w C # lub Java. Programiści C zwykle przechowują tylko połączenia zewnętrzne w pliku nagłówkowym. Wszystkie wywołania wewnętrzne byłyby zdefiniowane w pliku .c. Tym samym tokenem możesz zarezerwować swoje pliki C ++ .h dla klas / interfejsów (czysto wirtualne klasy abstrakcyjne) / etc. które mają być udostępniane poza biblioteką DLL. W przypadku klas wewnętrznych / struktur / interfejsów itp. Wystarczy dołączyć potrzebny plik .cpp:
Nie wydaje się to być najpopularniejszym podejściem, ale jest to legalne C ++. Z pewnością byłaby to możliwość dla całego twojego wewnętrznego kodu. Pozwala to wewnętrznemu kodowi i zestawowi klas na znacznie bardziej radykalną zmianę, zapewniając jednocześnie bardziej stabilny interfejs dla kodu poza biblioteką / plikiem wykonywalnym do interakcji.
Umieszczenie całej klasy w jednym pliku ułatwi robienie tego, co chcesz. Nie rozwiąże problemu zmiany nazwy metody i konieczności przeszukiwania każdego miejsca, w którym ta metoda jest wywoływana, ale zapewni bardziej zrozumiałe komunikaty o błędach. Nie ma nic gorszego niż to, że nagłówek deklaruje metodę w jedną stronę, ale implementujesz ją inaczej. Inny kod, który wywołuje plik nagłówkowy, zostanie poprawnie skompilowany i otrzymasz wyjątek łącza, podczas gdy plik implementacyjny będzie tym, który skarży się, że metoda nie została zdefiniowana. Kiedy zdefiniujesz każdą metodę na miejscu (w rzeczywistej deklaracji klasy), otrzymasz ten sam komunikat o błędzie bez względu na to, jaki plik ją zawiera.
Możesz także przyjrzeć się temu pytaniu: Dobre narzędzia refaktoryzujące dla C ++
Jak C / C ++ rozwiązuje pliki nagłówkowe / implementacyjne
Na podstawowym poziomie C (i C ++ jest zbudowany na tej podstawie) pliki nagłówkowe deklarują obietnicę funkcji / struct / zmiennej, która wystarcza, aby kompilator mógł utworzyć plik obiektowy. Podobnie pliki nagłówkowe C ++ deklarują obietnicę funkcji, struktur, klas itp. Jest to definicja, której używa kompilator do rezerwowania miejsca na stosie itp.
Pliki .c lub .cpp mają implementację. Gdy kompilator konwertuje każdy plik implementacji na plik obiektowy, istnieją niedostosowania do niezaimplementowanych pojęć (co zadeklarowano w nagłówku). Linker łączy zaczepy z implementacjami w innych plikach obiektowych i tworzy większy plik binarny, który zawiera cały kod (biblioteka współdzielona lub plik wykonywalny).
VS Specific
Jeśli chodzi o pracę z tymi w Visual Studio, istnieją pewne kreatory, które pomagają nieco to ułatwić. Kreator nowej klasy utworzy pasującą parę plików nagłówkowych i implementacyjnych. Istnieje nawet funkcja przeglądarki klasy, która pozwoli Ci zadeklarować nowe metody. Wprowadzi definicję do nagłówka i kod źródłowy implementacji w pliku .cpp. Visual Studio ma te funkcje od ponad dekady (o ile ich używałem).
źródło
Zostań programistą Java.
Jeśli naprawdę musisz kontynuować programowanie w C ++, możesz spróbować użyć IDE. Często oferują pewien mechanizm, za pomocą którego można dodać metodę do klasy, i to automatycznie umieszcza deklarację w pliku .h, a definicję w pliku .cpp.
źródło
Możesz być zainteresowany programem makeheaders od Hwaci (tych, którzy robią SQLite i Fossil).
Zobacz także, jak zbudowana jest skamielina, aby mieć pomysł.
źródło
Kiedy piszesz pierwsze wiersze nowej klasy, zwykle dzieje się tak, ponieważ potrzebujesz go tylko w jednym miejscu w tym czasie. Później może być używany w większej liczbie miejsc, ale początkowo zwykle nie jest.
Wiele moich zajęć zaczyna się na początku bieżącego pliku .cpp. Kiedy ustabilizuje się na tyle, że można go używać w wielu miejscach, wycinam i wklejam go do nagłówka. Chociaż często klasa znika tak szybko, jak się pojawiła.
źródło
Jako sugestię dotyczącą obsługi plików nagłówkowych C ++ często stosuje się je bez rozszerzenia pliku lub sufiksu, tak jak w przypadku bibliotek „GCC”.
W takim przypadku sugeruję użycie rozszerzenia lub sufiksu pliku „ .hpp” (lub co najmniej „ .hxx”).
Może być konieczne skonfigurowanie kompilatora, środowiska programisty lub programu wbudowanego.
źródło
#include <iostream>
? To nie są tylko dla biblioteki GCC. W rzeczywistości jest on zdefiniowany w standardzie C ++ z 1997 r. , Sekcja 17.3.1.2. Unikałbym nazywania takich plików. Możesz, ale powodem, dla którego zrobiła to standardowa biblioteka C ++, było prawdopodobnie uniknięcie konfliktów nazw. Wydaje mi się to naprawdę dziwne, gdy kompilatory automatycznie dodają „.h”, kiedy dołączasz nagłówek, wydaje mi się to dość niestandardowe. I nigdy nie widzę nagłówków nazw bez sufiksu, z wyjątkiem standardowej biblioteki c ++.#include <someclass>
że będziesz czytany jak#include <someclass.hpp>
we wszystkich kompilatorach. Twój kod się zepsuje.