There are three main reasons that get combined to explain this:
- They are two completely different "things". The syntax may look quite the same, but they do two completely different things in C++.
- The One Definition Rule
#include
ing a header file is logically equivalent, and is exactly equivalent to physically inserting the contents of the header file into whatever #include
d it.
So, in the first case, with a header file containing int variable = 0;
, every translation unit that #include
s this file becomes exactly as if
int variable = 0;
Appeared verbatim in every .cpp
file that #include
d it. Exactly the same. And, obviously, that's a One Definition Rule violation (if more than one .cpp
has this, and they are linked together). This actually creates an int
variable. It defines it. An object called variable
pops into existence, out of thin air. Every .cpp
file that includes this becomes a proud owner of an int variable
. It exists in every .cpp
file, and this violates the One Definition Rule.
On the other hand, you have a class declaration, here:
class Class{
public:
static int variable;
};
This does not define anything. It just declares a Class
, that has a static
class member. That's it. It does not define any object. It does not pop anything into existence, or materialize anything out of thin air. This just declares a class, and what's inside it. The One Definition Rule does not come into play for the elementary reason that nothing gets defined here.
So, despite very similar syntax, the end result of very similar looking code is quite different, in C++.