0

I am trying to count the number of instances of a class by modifying a static data member:


class C
{
public:
    static unsigned int i;
    C(){i++;}
};

this shows an error:
Main.obj : error LNK2001: unresolved external symbol "public: static unsigned char C::i" (?i@C@@2EA)

please help me out here by either editing this code for appropriate functioning or letting me know the solution to this problem without the use of any global variable.
Your answers will be appreciated.
Thank You.

  • just add `unsigned int C::i = 0;` after class declaration and it shoud work – Marek Janoud Oct 02 '16 at 06:30
  • Also, http://stackoverflow.com/questions/15845745/lnk2001-error-when-accessing-static-variables-c, http://stackoverflow.com/questions/16049306/error-lnk2001-unresolved-external-symbol-private-static-class and many many others. – AnT stands with Russia Oct 02 '16 at 06:35

1 Answers1

0

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.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • Why the `auto` stuff instead of the shorter and easier to read `static int& n() { static int n; return n; }` ? – 6502 Oct 02 '16 at 06:36
  • @Cheers: Thank you, that answers my question and is helpful in many similar situations. – Suhas Srivastava Oct 02 '16 at 06:38
  • @6502: The old function declaration syntax' very limited area of applicability is completely covered by the new syntax. It is silly to use two syntaxes for the same thing. I don't agree about readability; on the contrary, the old syntax sucks wrt. readability, especially with longer template expressions for the return type (also with the need to qualify a return type that has class scope). – Cheers and hth. - Alf Oct 02 '16 at 06:40