Ok, not a C/C++ expert by any means, but I thought the point of a header file was to declare the functions, then the C/CPP file was to define the implementation.
However, reviewing some C++ code tonight, I found this in a class's header file...
public: UInt32 GetNumberChannels() const { return _numberChannels; } // <-- Huh?? private: UInt32 _numberChannels;
So why is there an implementation in a header? Does it have to do with the const
keyword? Does that inline a class method? What exactly is the benefit/point of doing it this way vs. defining the implementation in the CPP file?
In C language, header files contain the set of predefined standard library functions. You request to use a header file in your program by including it with the C preprocessing directive “#include”. All the header file have a '. h' an extension.
The header file eliminates the labor of finding and changing all the copies as well as the risk that a failure to find one copy will result in inconsistencies within a program. In C, the usual convention is to give header files names that end with .
The header file contains only declarations, and is included by the . c file for the module. Put only structure type declarations, function prototypes, and global variable extern declarations, in the . h file; put the function definitions and global variable definitions and initializations in the .
The answer to the above is yes. header files are simply files in which you can declare your own functions that you can use in your main program or these can be used while writing large C programs. NOTE:Header files generally contain definitions of data types, function prototypes and C preprocessor commands.
Ok, not a C/C++ expert by any means, but I thought the point of a header file was to declare the functions, then the C/CPP file was to define the implementation.
The true purpose of a header file is to share code amongst multiple source files. It is commonly used to separate declarations from implementations for better code management, but that is not a requirement. It is possible to write code that does not rely on header files, and it is possible to write code that is made up of just header files (the STL and Boost libraries are good examples of that). Remember, when the preprocessor encounters an #include
statement, it replaces the statement with the contents of the file being referenced, then the compiler only sees the completed pre-processed code.
So, for example, if you have the following files:
Foo.h:
#ifndef FooH #define FooH class Foo { public: UInt32 GetNumberChannels() const; private: UInt32 _numberChannels; }; #endif
Foo.cpp:
#include "Foo.h" UInt32 Foo::GetNumberChannels() const { return _numberChannels; }
Bar.cpp:
#include "Foo.h" Foo f; UInt32 chans = f.GetNumberChannels();
The preprocessor parses Foo.cpp and Bar.cpp separately and produces the following code that the compiler then parses:
Foo.cpp:
class Foo { public: UInt32 GetNumberChannels() const; private: UInt32 _numberChannels; }; UInt32 Foo::GetNumberChannels() const { return _numberChannels; }
Bar.cpp:
class Foo { public: UInt32 GetNumberChannels() const; private: UInt32 _numberChannels; }; Foo f; UInt32 chans = f.GetNumberChannels();
Bar.cpp compiles into Bar.obj and contains a reference to call into Foo::GetNumberChannels()
. Foo.cpp compiles into Foo.obj and contains the actual implementation of Foo::GetNumberChannels()
. After compiling, the linker then matches up the .obj files and links them together to produce the final executable.
So why is there an implementation in a header?
By including the method implementation inside the method declaration, it is being implicitly declared as inlined (there is an actual inline
keyword that can be explicitly used as well). Indicating that the compiler should inline a function is only a hint which does not guarantee that the function will actually get inlined. But if it does, then wherever the inlined function is called from, the contents of the function are copied directly into the call site, instead of generating a CALL
statement to jump into the function and jump back to the caller upon exiting. The compiler can then take the surrounding code into account and optimize the copied code further, if possible.
Does it have to do with the const keyword?
No. The const
keyword merely indicates to the compiler that the method will not alter the state of the object it is being called on at runtime.
What exactly is the benefit/point of doing it this way vs. defining the implementation in the CPP file?
When used effectively, it allows the compiler to usually produce faster and better optimized machine code.
It is perfectly valid to have an implementation of a function in a header file. The only issue with this is breaking the one-definition-rule. That is, if you include the header from multiple other files, you will get a compiler error.
However, there is one exception. If you declare a function to be inline, it is exempt from the one-definition-rule. This is what is happening here, since member functions defined inside a class definition are implicitly inline.
Inline itself is a hint to the compiler that a function may be a good candidate for inlining. That is, expanding any call to it into the definition of the function, rather than a simple function call. This is an optimization which trades the size of the generated file for faster code. In modern compilers, providing this inlining hint for a function is mostly ignored, except for the effects it has on the one-definition-rule. Also, a compiler is always free to inline any function it sees fit, even if it has not been declared inline
(explicitly or implicitly).
In your example, the use of const
after the argument list signals that the member function does not modify the object on which it is called. In practice, this means that the object pointed to by this
, and by extension all class members, will be considered const
. That is, trying to modify them will generate a compile-time error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With