I know that inline member functions by definition should go into the header. But what if it's not possible to put the implementation of the function into the header? Let's take this situation:
File A.h
#pragma once
#include "B.h"
class A{
B b;
};
File B.h
#pragma once
class A; //forward declaration
class B{
inline A getA();
};
Due to the circular include I have to put the implementation of getA
into
B.cpp
#include "B.h"
#include "A.h"
inline A B::getA(){
return A();
}
Will the compiler inline getA
? If so, which inline keyword is the significant one (the one in the header or the one in the .cpp file)? Is there another way to put the definition of an inline member function into its .cpp file?
It can't, outside the scope of B.cpp. The compiler operates on a per-compile-unit base, i.e. it compiles each .cpp file individually, so if it compiles C.cpp, it won't have the code for getA() available and will need to perform a function call and have the linker fix it up (or, if it really took you by the word and tried to inline, it will have end up with a linker error.
inline
has similar qualities asstatic
).The only exception is LTCG, i.e. link-time code generation, which is available on newer compilers.
One approach in this case is to have another header file (sometimes named *.inl files) that contain the inlined code.
EDIT: As for which inline is relevant - it's the one in the class definition, i.e. in the header file. Keep in mind that many compilers have their own mind on what can and should be inlined. gcc for example can disable inlining completely (-O0), or it can inline anything that it deems worth inlining (like -O3).
I would go about this from the opposite direction.
Don't add inline declarations to your function (unless you need too).
The only time you need to add the inline declaration to a function/method is if you define the function in a header file but outside the class declaration.
X.h
X.cpp
To you more specific case.
Remove all the inline specifications. They are not doing what you think they are doing.
Here is the way I did it.
File A.h
File B.h
File C.h
Just include the "C.h" file to be able to use getA() method. The only change with the original code is that the getA() method must be defined as public instead of private.
However, as many of you explained it, this is not really useful.
Quoting from C++ FAQ:
The compiler need to see the definition of the inline function whenever it finds any use of that inline function. That is typically possible if the inline function is placed in a header file.
No, except when the the use of
getA()
is in B.cpp itself.Best practice: only in the definition outside the class body.
No, at least I don't know.
ISO/IEC 14882:2014
These days, most compilers can perform inlining at link time, as well as compile time. If your function is likely to benefit from inlining, then the Link Time optimizer is likely to do just that.
By the time the linker gets to it, not much about the inline status of compiler output is available, except that the compiler will flag certain objects as being collectible, for instance because an inline function or class template instance appears in multiple compilation units, or it should raise an error when multiple symbols share a name, such as the main function being defined twice. None of this has influence on the actual code it will generate.