Within a class definition static data members are declared bur not defined. So you may even to use a non-complete type in a declaration of a static data member inside a class definition.
For example
struct A
{
static int a[];
};
int A::a[10];
Here in this example the declaration of the data member a within the class definition has an incomplete array type (the number of elements of the array is unknown).
Starting from C++ 17 you may declare a static data member as an inline member. For example
class Person {
inline static int id = 0;
public:
void createPerson() {
id++;
cout << id << endl;
}
};
In this case you may initialize it in the declaration inside the class definition.
Otherwise you may initialize a static data member within a class definition only if it is declared as having an integral type and has the qualifier const
or the specifier constexpr
(in the last case the static data member will be an inline declaration).
But if a static data member is declared as a const object nevertheless you have to define it outside the class if for example you will try to get the address of the static data member. For example this code is invalid
#include <iostream>
using namespace std;
class Person {
const static int id = 0;
public:
void createPerson() {
cout << &id << endl;
}
};
int main()
{
Person Person1;
Person Person2;
Person1.createPerson();
Person2.createPerson();
}
As there is the address of the static data member is taken then you have to define the static data member.
#include <iostream>
using namespace std;
class Person {
const static int id = 0;
public:
void createPerson() {
cout << &id << endl;
}
};
const int Person::id;
int main()
{
Person Person1;
Person Person2;
Person1.createPerson();
Person2.createPerson();
}
This program will compile.