2012-09-04 19 views
5

Powiel możliwe:
Inline functions in C++Co się stanie, jeśli zaimplementuję klasę w pliku nagłówkowym?

Jaki kompilator zrobić, jeśli całkowicie zaimplementować klasę w jego pliku nagłówka? Typowym przykładem następująco:

class MyException 
{  
public: 
    explicit MyException(const char* file, int line) file(file), line(line) {}; 
    const char* getFile() const { return file }; 
    int getLine() const { return line }; 
private: 
    const char* const file; 
    const int line; 
}; 

Moją intencją jest, aby korzystać z klasy tak: throw MyException(__FILE__, __LINE__).

Dołączę ten plik nagłówkowy do każdego pliku .cpp. Przypuszczam, że kompilator skompiluje klasę tyle razy, ile jest zdefiniowane i dołącza (identyczny) kod maszynowy do każdego tworzonego pliku obiektu. Co zrobi linker? Próbowałem prostszego przykładu (bez tych wszystkich brzydkich const) i skompilowałem go dobrze.

Co by się stało, gdyby zamiast prostej klasy zaimplementowałem funkcję C-screen o trzech ekranach w pliku nagłówkowym? I ostatnie pytanie, czy powinienem podzielić mój przykład na pliki .h i .cpp?

+7

Metody zastosowane w definicji klasy są wbudowane. –

+1

Dla krótkiej klasy takiej jak ta nie ma sensu dzielenie jej na .h i .cpp. – alfa

+0

Będzie działał dobrze, o ile nie uwzględnisz wyjątku w 2 bibliotekach i nie wyrzucisz tego execocation przez granice bibliotek w systemie Linux. Środowisko wykonawcze uzna wersję 2 wyjątku za odmienną, a funkcja catch (MyException &) w bibliotece A może nie działać z powodu wyrzucenia wyjątku MyException z biblioteki B – gastush

Odpowiedz

3

Definicja klasy nie generuje żadnego kodu. Pokazuje tylko użytkownikom klasy, w jaki sposób jest rozmieszczona, aby mogli wygenerować odpowiedni kod do manipulowania nim.

To funkcje składowe klasy, które generują kod. Po zdefiniowaniu funkcji składowej w definicji klasy, funkcja ta daje niejawną deklarację inline.

Połączenie funkcji mogą być zestawiane i łączone w jeden z dwóch sposobów:

(1) w jednym egzemplarzu kodu funkcji z instrukcją montażu zwrotu na koniec może być umieszczony w obrazie, a połączeniem Instrukcja montażu może zostać umieszczona (wraz z przekazywaniem parametrów i przesyłaniem wartości zwrotu) w miejscu połączenia, aby przekazać sterowanie do tego kodu.

lub

(2) Cała kopia realizacji funkcji można wymienić cały wywołanie funkcji w miejscu wywołania.

Funkcja zadeklarowana jako inline jest zaleceniem dla kompilatora, aby zrobić to w drugą stronę. Ponadto deklaracja inline pozwala zdefiniować funkcję w kilku jednostkach tłumaczeniowych (dzięki czemu można ją umieścić we współdzielonym pliku nagłówkowym). Aby kompilator miał opcję implementacji drugiej metody, potrzebuje kopii implementacji funkcji podczas kompilacji. Nie jest to możliwe, jeśli implementacja funkcji odbywa się w zagranicznej jednostce tłumaczeniowej.

Należy również zauważyć, że współczesne kompilatory wykonują skomplikowane czynności za pomocą funkcji zadeklarowanych jako wbudowane. Zobacz:

http://gcc.gnu.org/onlinedocs/gcc/Inline.html

+2

Występuje subtelna różnica między funkcją inline i funkcją inlined. –

+0

Należy dodać, że wbudowane funkcje _may_ mogą być rozwijane w linii. Nie oni będą ... Ale funkcje inline też mogą być rozszerzone także inline. – jcoder

+1

Ważniejszym znaczeniem słowa "inline" jest to, że funkcja może być zdefiniowana w wielu jednostkach tłumaczeniowych, a kompilator/linker/cokolwiek jest potrzebne do utworzenia tylko jednej kopii w ostatecznym programie. Jest to bezpośrednio związane z pytaniem (ponieważ członkowie klasy są niejawnie wbudowane, a zatem definicja klasy może być zawarta w wielu jednostkach tłumaczeniowych), natomiast jakikolwiek wpływ, jaki może mieć na decyzję o wprowadzeniu konkretnych wywołań funkcji, nie ma znaczenia. –

3

Wszystkie metody będą metody inline. Możesz stracić trochę czasu na ogólnej kompilacji, ale jest w porządku. O ile mi wiadomo, jedynym problemem, który może wystąpić, jest statyczna zmienna członkowska. Następnie musisz przypisać do niego miejsce do przechowywania (umieść definicję i wartość początkową, jeśli chcesz) prawdopodobnie w .cpp, inaczej otrzymasz błędy linkera dotyczące wielu definicji.

Widziałem projekty tylko nagłówkowe, które miały tylko funkcję main() w CPP, ale to było silnie szablonowe.

3

Po zaimplementowaniu funkcji składowych w pliku nagłówkowym wszystkie te funkcje stają się niejawnie inline.

Co to oznacza i jakie ma to konsekwencje?

Zgodnie, C++ 03 Standardowe §7.1.3/4:

  • to kompilator wskazówki, że podstawienie funkcji organizmu w miejscu połączenia jest preferowane przez zwykłe mechanizm wywoływania funkcji.
  • Nawet jeśli pominięto podstawienie, obowiązują inne reguły (szczególnie w.r.t Jedna definicja reguły) dla wstawianych.

Tak Tak, każda jednostka tłumaczenie będzie mieć definicję inline function.This może wynik na zwiększenie wielkości plików binarnych.

Zazwyczaj każdy dobry nurt kompilator zastąpi ciało funkcji w punkcie połączenia w razie potrzeby, więc oznaczenie funkcji inline tylko dla # 1 nie jest to dobry pomysł, ale jeśli chcesz, aby Twój intencją jasne dla użytkowników klasy, możesz to zrobić, definiując funkcje w nagłówku lub jawnie oznaczając swoje funkcje jako inline.

powinienem podzielić moim przykładem na .h i .cpp plików?

Tak, to jest zwykle modelu kompilacja że większość projektów użyciu, w którym oddzielić interfejs (.h) z realizacji (.cpp) .Powierzchnia interfejsy są udostępniane użytkownikom kodzie jak pliki nagłówkowe, podczas gdy implementacja jest dostarczana w postaci plików binarnych. Do pewnego stopnia zapewnia to zabezpieczenie Twojej własności intelektualnej.
Jest to znany jako model separacji.

C++ projekty wykorzystujące szablony zazwyczaj użyć Integracji model zamiast separacji Model zwykłych projektów C++.

Powiązane problemy