2009-10-16 7 views
9

Czy jest coś złego w tym, że jedna klasa (jedna .h) została zaimplementowana na wielu plikach źródłowych? Zdaję sobie sprawę, że może to być objaw zbyt dużej ilości kodu w pojedynczej klasie, ale czy jest w tym coś złego?Jedna klasa z wieloma plikami implementacyjnymi

Na przykład:

Foo.h

class Foo 
{ 
    void Read(); 
    void Write(); 
    void Run(); 
} 

Foo.Read.cpp

#include "Foo.h" 
void Foo::Read() 
{ 
} 

Foo.Write.cpp

#include "Foo.h" 
void Foo::Write() 
{ 
} 

Foo.Run.cpp

#include "Foo.h" 
void Foo::Run() 
{ 
} 

Odpowiedz

13

To jest w porządku. W końcu wszystko będzie połączone razem.

Widziałem nawet kod, w którym każda funkcja członka znajdowała się w innym pliku * .cpp.

+1

To by mnie popchnęło. Jestem pewien, że istnieją czasami dobre (lub przynajmniej przyzwoite) powody, aby to zrobić, ale z perspektywy próby zrozumienia modelu obiektu, bleah ... aby przeskakiwać pliki, aby podążać za metodami. – Joe

+1

Jeśli tworzysz bibliotekę, dzielenie każdej funkcji i globalnej na własny obiekt pozwala konsumentowi połączyć tylko te bity, których dotyczą, i nic więcej. Z irytacją jest jednak pracować. – ephemient

+1

@ephemient: Dlaczego to ma znaczenie? Czy linker nie może usunąć funkcji, których nie używasz? Czy jest to po prostu dla poprawy czasów połączeń? –

4

Nie, nic z tym nie jest technicznie w porządku. Łącznik przyniesie wszystkie kawałki Foo razem w końcowym pliku binarnym.

1

Pracowałem z Apache Portable Runtime, który robi dokładnie to samo. Masz nagłówek, na przykład apr_client.h i wiele plików implementacji dla funkcji w tym nagłówku - każdy plik reprezentuje jeden aspekt operacji klienta. To nie jest złe i nie jest to niezwykłe.

to może być objawem zbyt dużej ilości kodu w jednej klasie

C++ nie jest Java, dzięki czemu nie trzeba wybierać swoje nazwy plików zgodnie ze swoimi nazwami klas.

0

tak, to jest uzasadnione, a w rzeczywistości nowsze języki, takie jak C#, robią tego rodzaju rzeczy przez cały czas.

6

To jest uzasadnione i ma kilka (!?) Zalety ...

Jeśli połączyć swój plik wykonywalny z biblioteki statycznych tej klasy, tylko używane funkcje dostanie w. Jest to bardzo przydatne dla ograniczonej - systemy źródłowe.

Można również ukryć szczegóły implementacji niektórych funkcji. Dwie osoby mogą implementować części klasy, nie wiedząc o sobie nawzajem. Poręczny dla projektów DOD.

Jeśli spojrzeć na źródła CRT, widać ten sam wzór ...

+1

Punkt ponownie ukrywający szczegóły implementacji dla tej samej klasy naprawdę ją rozciąga. Jeśli masz klasę, która może być tak łatwo podzielona, ​​to powinna być 2 klasy, a nie jedna. –

+0

@Richard: Chciałem tylko powiedzieć, że możesz to zrobić, nie musisz tego robić. Jeśli funkcja jest tak prosta, możesz nie chcieć stworzyć dla niej osobnej klasy ... – Malkocoglu

+1

@Richard - eh? - co z "urządzeniem", na przykład foo :: read foo :: write foo :: ioctl, co z korzyściami krótszych czasów budowy? – pgast

2

Jest całkowicie poprawny. Wszystkie pliki cpp będą ze sobą połączone.

Może to być przydatne, jak powiedziałeś, dzięki czemu bardzo duży plik implementacji stanie się bardziej czytelny, a ponieważ każdy plik cpp jest jednostką kompilującą, możesz (ab) użyć tego faktu. (Nienazwane przestrzenie nazw)

+0

+ za wzmiankę o zwiększonej możliwości wewnętrznego powiązania –

0

Są dwa punkty, które mogą być warte rozważenia.

klasy szerokości optymalizacje:

Jeśli kompilator wszystkich funkcji składowych widocznych nim podczas jej przetwarzania plik (przy założeniu pojedynczej kompilator TU), to może on być w stanie wykonywać optymalizacje między różnymi członka Funkcje.

Code Review

Jeśli wszystkie definicje dla klasy są w tym samym TU, to sprawia, że ​​instrukcja ocena kod łatwiejsze. Jeśli definicje są podzielone na różne jednostki tłumaczeniowe, znacznie zwiększa to wysiłek wymagany do ręcznego przeglądu, ponieważ należy wyszukiwać odpowiednie pliki, z ciągłym przesuwaniem między oknami, aby uzyskać "cały" obraz.

Powiązane problemy