A direct static data member that's assigned to needs a definition. Basically the definition allocates memory. Goes like this:
class C
{
private:
static int i; // pure declaration
public:
static auto n_instances() -> int { return i; }
~C() { --i; }
C(){ ++i; }
C( C const& ) { ++i; }
};
int C::i; // definition
In a header file that is impractical (if the header is used in multiple translation units it will be in violation of the One Definition Rule, with the linker complaining), so then you can use the following technique:
class C
{
private:
static auto n()
-> int&
{
static int the_count = 0;
return the_count;
}
public:
static auto n_instances() -> int { return n(); }
~C() { --n(); }
C(){ ++n(); }
C( C const& ) { ++n(); }
};
There are also other ways to do this, including the template trick and C++17 inline
data.
I chose to use int
instead of unsigned
because int
is good for integer numbers, while unsigned
is good for bit-level stuff, but not vice versa.
Disclaimer: code not touched by compiler.