Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++] Implementacja metody poza definicją klasy w pliku nagłówkowym

Ostatnio zmodyfikowano 2013-09-05 15:21
Autor Wiadomość
DejaVu
Temat założony przez niniejszego użytkownika
[C++] Implementacja metody poza definicją klasy w pliku nagłówkowym
» 2013-09-05 14:44:51
C/C++
class CKlasa
{
public:
    int metoda();
};

int CKlasa::metoda()
{
    return 0;
}
Czy da radę uzyskać powyższy efekt mając całe źródła w pliku nagłówkowym? Chciałbym mieć definicję klasy w pliku nagłówkowym jak również kilka metod, ale nie chcę, aby kod metod był zawarty wewnątrz definicji klasy po to, aby definicja była czytelniejsza.

error LNK2005: "public: __thiscall cmn::TAllocator::TAllocator(void)" (??0TAllocator@cmn@@QAE@XZ) already defined in AllocatorSystem.obj
error LNK2005: "public: virtual __thiscall cmn::TAllocator::~TAllocator(void)" (??1TAllocator@cmn@@UAE@XZ) already defined in AllocatorSystem.obj
fatal error LNK1169: one or more multiply defined symbols found
Obecnie dla analogicznego przypadku otrzymuję powyższe błędy kompilacji, które można rozwiązać albo poprzez wciągnięcie implementacji metod do definicji klasy, albo poprzez wyciągnięcie implementacji metod do pliku *.cpp.

Z tego co wiem to metody wyrzucone do pliku *.cpp nie mogą być inline-owane przez kompilator (za wyjątkiem metod krótkich wywoływanych przez inne metody tej samej klasy). Stąd mam potrzebę zamieszczenia implementacji wybranych metod w pliku *.hpp, ale nie wiem czy istnieje jakiś trick składniowy, który umożliwia wykonanie dokładnie tego co opisałem na samym początku.
P-91556
akwes
» 2013-09-05 14:51:47
Czyli jeżeli dałoby się zmusić funkcję do bycia inline to problemu by nie było?

http://msdn.microsoft.com​/en-us/library/z8y1yy88.aspx
__forceinline
?

// Edit,
z tego co pamiętam to korzystasz z Visuala
P-91557
pekfos
» 2013-09-05 14:56:39
A co ze zwykłym inline?
P-91558
DejaVu
Temat założony przez niniejszego użytkownika
» 2013-09-05 14:56:53
__forceinline to tylko sugestia dla kompilatora i nie ma żadnej gwarancji, że zostanie ona zastosowana. W zasadzie używanie jakiegokolwiek słowa kluczowego 'inline' jest w dzisiejszych czasach pozbawione sensu...

/edit:
The compiler treats the inline expansion options and keywords as suggestions. There is no guarantee that functions will be inlined. You cannot force the compiler to inline a particular function, even with the __forceinline keyword. When compiling with /clr, the compiler will not inline a function if there are security attributes applied to the function.
a to cytat z MSDN-a do którego daliście linka :P
P-91559
akwes
» 2013-09-05 15:00:28

The __forceinline keyword overrides the cost/benefit analysis and relies on the judgment of the programmer instead.
Na pewno jest tylko sugestią? Zawsze czytałem, że jest to wymuszenie aby funkcja była inline a nie sugestia.

Hm...

Even with __forceinline, the compiler cannot inline code in all circumstances. The compiler cannot inline a function if:
The function or its caller is compiled with /Ob0 (the default option for debug builds).
The function and the caller use different types of exception handling (C++ exception handling in one, structured exception handling in the other).
The function has a variable argument list.
The function uses inline assembly, unless compiled with /Og, /Ox, /O1, or /O2.
The function is recursive and not accompanied by #pragma inline_recursion(on). With the pragma, recursive functions are inlined to a default depth of 16 calls. To reduce the inlining depth, use inline_depth pragma.
The function is virtual and is called virtually. Direct calls to virtual functions can be inlined.
The program takes the address of the function and the call is made via the pointer to the function. Direct calls to functions that have had their address taken can be inlined.
The function is also marked with the naked __declspec modifier.
If the compiler cannot inline a function declared with __forceinline, it generates a level 1 warning.
Czyli jeżeli nie uda się inlineować, to wiadomo to z góry i będzie warrning. Myślę, że można by chociaż spróbować?
P-91560
DejaVu
Temat założony przez niniejszego użytkownika
» 2013-09-05 15:08:36
To wyobraź sobie scenariusz:
1) kompilujesz bibliotekę, która ma metodę publiczną size(), z force inline.
2) w drugim projekcie używasz pliku nagłówkowego i skompilowanej statycznie biblioteki.
3) jak kompilator ma ci zrobić inline, skoro biblioteka została już skompilowana, a w pliku nagłówkowym nie masz jej deklaracji?

/edit:
No chyba, że linker jeszcze robi jakieś cuda optymalizacyjne...

/edit2:
No w sumie to w linkerze są ustawienia dot. optymalizacji kodu :) No ale i tak nadal pozostaje pytanie otwarte, tj. co on zrobi ze skompilowanym kodem z biblioteki.
P-91561
pekfos
» 2013-09-05 15:15:16
Definicja funkcji inline musi być w każdej jednostce translacji, w której jest używana.
P-91562
Elaine
» 2013-09-05 15:16:05
Słowo kluczowe, którego szukasz, to inline. Problemem jest tylko jego nazwa: obecnie jego głównym znaczeniem nie jest żaden hint dla kompilatora (choć wiele kompilatorów wciąż z tego jako hintu korzysta), tylko wymuszenie złagodzenia ODR, czyli dokładnie to, czego potrzebujesz. Lepszą nazwą byłoby pewnie relaxed_odr. W każdym razie:
C/C++
class Foo {
public:
    void doStuff();
};

inline void Foo::doStuff() {
}

Z tego co wiem to metody wyrzucone do pliku *.cpp nie
mogą być inline-owane przez kompilator
Mamy 2013 rok, kompilatory nie takie rzeczy potrafią. Szczególnie, że w VC++ generowanie kodu w trakcie linkowania jest w trybie release ustawieniem domyślnym.
P-91563
« 1 » 2
  Strona 1 z 2 Następna strona