Reputation: 31
I am new to c++ and experimenting with classes and static variables.
I have found the solution to making the code run but I am not sure why this works and why my previous method did not
#include <iostream>
using namespace std;
class Person {
static int id;
public:
void createPerson() {
id++;
cout << id << endl;
}
};
int Person::id = 0;
int main() {
Person Person1;
Person Person2;
Person1.createPerson();
Person2.createPerson();
}
I am wondering why I must declare the value of id outside the class. And why I cannot have something like..
class Person {
static int id = 0;
public:
void createPerson() {
id++;
cout << id << endl;
}
};
Upvotes: 3
Views: 439
Reputation: 136306
static
data members are not parts of objects, so you need to tell the compiler explicitly in which translation unit to store them by providing that definition.
Note that static data members of class templates can be defined in the header files.
In C++17 a static
data member can be declared as inline
, so that no out-of-line definition is necessary.
Upvotes: 4
Reputation: 311038
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.
Upvotes: 0
Reputation: 2117
Adding the inline
keyword will do the job. Simply change your line to:
static inline int id = 0;
Another possibility would be, but only if your value is constant, to declare it like this:
static inline constexpr int id = 0;
This is the preferred way for declaring global constants instead of using #define
s.
Upvotes: 2