One important point to note is that if a member function is defined inside a header file, it must be either inside the class body or it must be marked explicitly as inline
. In other words, it is plain wrong to do this in a header file:
class A {
public:
A();
};
A::A() {
// constructor body
}
The reason it's wrong is because it will make the compiler include the definition in each compilation unit, while it's obvious that any function must be defined only once. Here are correct ways to do the same thing:
class A {
public:
inline A();
};
inline A::A() {
// constructor body
}
Or:
class A {
public:
inline A() { // inline isn't required here, but it's a good style
// constructor body
}
};
In both cases the constructor is inline. The only correct way to make it a regular out-of-line function would be to define it in the implementation file, not in the header. This is the most important difference between these two approaches.
Now, it is worth noting that inlining is an optimization. And as always with optimizations, they are best avoided until proved necessary. Among other problems inlining can lead to, there is the compatibility problem: if you change the body of a function that is not inlined, you only need to recompile the unit where it is defined, and everyone starts using the new implementation right away. With inlined functions, you need to recompile every unit that includes the relevant header, which can be a pain, especially if the header is used across different projects by different people.
In other words, use regular out-of-line definitions wherever possible until it is proved by profiling that a particular function call is a performance bottleneck. The only reasonable exception to this rule are trivial setters and getters, and even with them it is better to be careful - one day they may become non-trivial and it will mean a lot of recompilation and compatibility breaking.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…