I aware of three different kind of implementation "locations" for my class methods:
1) Define the method inside my class (.h file) and implement it in my .cpp file
//.h
class Foo
{
int getVal() const;
};
//.cpp
int Foo::getVal() const
{ return 0; }
2) Define and implement the method inside my class (.h file).
//.h
class Foo
{
int getVal() const
{ return 0; }
};
3) Define the method inside my class and implement it outside the class but inside my header file.
//.h
class Foo
{
int getVal() const;
};
int Foo::getVal() const
{ return 0; }
What are the main differences between these three approaches?
A class method is a method which is bound to the class and not the object of the class. They have the access to the state of the class as it takes a class parameter that points to the class and not the object instance. It can modify a class state that would apply across all the instances of the class.
Class methods are used when we are dealing with factory methods. Factory methods are those methods that return a class object for different use cases. Thus, factory methods create concrete implementations of a common interface. The class method can be called using ClassName.
Class methods are typically useful when we need to access the class itself — for example, when we want to create a factory method, that is a method that creates instances of the class. In other words, classmethods can serve as alternative constructors.
Classes provide a means of bundling data and functionality together. Creating a new class creates a new type of object, allowing new instances of that type to be made. Each class instance can have attributes attached to it for maintaining its state.
There are three elements to this question: readability (how good the code looks), compilation (how much the compiler can optimize it) and implementation hiding (If you use the code as a library, you may not want to explicitly share your special sauce with the world).
Method one exposes only the interface for the function in the header file. This means you show a nice clean interface, and your implementation is not exposed in plaintext. However, the code cannot be inlined across compilation units, so it has the potential to be a little slower in runtime (in practice, this only matters for a very, very very small percentage of the code). THIS SHOULD BE YOUR DEFAULT WAY TO GO.
Method 2 is implicit inlining. Long functions will clutter up your class which (imho) is bad. Also exposes your implementation to the world. However, the function can be inlined and is less verbose than defining it in another place. I reserve this for very small functions.
Method 3 is actually illegal, as you will break the one-definition rule, but the following is fine:
//Foo.h
class Foo {
int getVal() const;
};
inline int Foo::getVal() const {
return 0;
}
I use this when I want to keep the class definition clean but want the function definition in the header file (for inlinable or template functions).
(1) will compile faster for a large project (only have to compile the definition of getVal
once in Foo.cpp, and only have to recompile one thing if definition changes), and you get a very clear interface for a class for people who want to look it up. On the other hand, you can't inline getVal()
.
(2) and (3) will compile slower and add way more dependencies to your definitions changing. But you can inline getVal()
. Also this is required if getVal
is a template function. NOTE (3) will cause linker errors if your header is included multiple times - you'll have to mark remember to label your function inline
. This is a good reason to prefer (1) and (2) to (3).
Really it's not a matter of picking (1) vs (2). You will probably use both in large projects - put the definitions of the functions that should be inlined (and templates) in the header, and put the ones that inlining makes less sense for in the cpp.
A minor note before I begin, there are lots of words that are very similar used to describe these things, I will be using declaration for the portion in the header file (int getVal() const
) and implementation for the portion in the cpp file (int Foo::getVal() const
). Apologies if these aren't perfectly accurate.
Also note that benefits are penalties for the others, in case that isn't clear.
1) Define the method inside my class (.h file) and implement it in my .cpp file
This is considered the standard method, and generally accepted to be the default (there are numerous exceptions, so default might be a little strong).
It separates the declaration from the implementation. This provides a few benefits:
2) Define and implement the method inside my class (.h file).
This is called an inline implementation, it should be used in simple implementations only. It has a few benefits too:
3) Define the method inside my class and implement it outside the class but inside my header file.
I haven't seen this before, but would assume it is used when the definition is non-trivial but you want the inline benefits of 2. IdeaHat mentions that the inline
keyword is required in this case.
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