Soroush Rabiei
Soroush Rabiei

Reputation: 10868

How to access static members of a class?

I am starting to learn C++ and Qt, but sometimes the simplest code that I paste from a book results in errors.

I'm using g++4.4.2 on Ubuntu 10.04 with QtCreator IDE. Is there a difference between the g++ compiler syntax and other compilers? For example when I try to access static members something always goes wrong.

#include <iostream>
using namespace std;
class A
{
   public:
      static int x;
      static int getX() {return x;}
};
int main()
{
   int A::x = 100; // error: invalid use of qualified-name 'A::x'
   cout<<A::getX(); // error: : undefined reference to 'A::x'
   return 0;
}

I think it's exactly the same as declared here and here (isn't it?). So what's wrong with the above code?

Upvotes: 42

Views: 86919

Answers (9)

felix_1
felix_1

Reputation: 51

You can use the inline keyword since c++ 17 in front of static members to avoid a definition outside of class scope. Your code should now look like this:

#include <iostream>
using namespace std;
class A
{
   public:
      inline static int x;
      static int getX() {return x;}
};
int main()
{
   A::x = 100;    //Works now
   cout<<A::getX()<<'\n';
   return 0;
}

Upvotes: 5

Loki Astari
Loki Astari

Reputation: 264381

Try:

#include <iostream>
using namespace std;
class A
{
   public:
      // This declares it.
      static int x;
      static int getX(){return x;}
};

// Now you need an create the object so
// This must be done in once source file (at file scope level)
int A::x = 100;


int main()
{
   A::x = 200;
   // Notice no 'int' keyword before A::x on this line. You can modify A::x

   cout<<A::getX(); // Should work
   return 0;
}

Upvotes: 9

Shubham Singh
Shubham Singh

Reputation: 111

You need to define the static member variable of the class outside the class as static member variables require declaration as well as definition.

#include <iostream>
using namespace std;
class A
{
   public:
      static int x;
      static int getX() {return x;}
};

int A::x;         // STATIC MEMBER VARIABLE x DEFINITION

int main()
{
   A::x = 100;    // REMOVE int FROM HERE
   cout<<A::getX();
   return 0;
}

Upvotes: 11

Eswaran Pandi
Eswaran Pandi

Reputation: 670

Case 1: static variable

As we all know, defining a static variable inside a class which will throw compilation error. E.g. below

class Stats
{
  public: 
     static int AtkStats[3];
     *static int a =20;*        // Error: defining a value for static variable
};

int Stats::AtkStats[3] =  {10, 0, 0};

Output:

error: ISO C++ forbids in-class initialization of non-const static member 'Stats::a'

Case 2: const static variable

For const static variable, we can define a value either inside a class or Outside class.

class Stats
{
  public: 
     static const int AtkStats[3];
     static const int a =20;        // Success: defining a value for a const static
};

const int Stats::AtkStats[3] =  {10, 0, 0};

const int Stats::a = 20;        // we can define outside also

Output:

Compilation success.

Upvotes: 0

You've declared the static members fine, but not defined them anywhere.

Basically what you've said "there exists some static member", but never set aside some memory for it, you need:

int A::x = 100;

Somewhere outside the class and not inside main.

Upvotes: 59

Naresh
Naresh

Reputation: 155

Try this example:

#include<iostream>
using namespace std;

class check
{
        static int a;
    public:
        void change();
} ;
int check::a=10;
void check::change()
{
    a++;
    cout<<a<<"\n";
}

int main()
{

    int i,j;
    check c;
    check b;
    c.change();
    b.change();
    return 0;
}

Upvotes: 3

CashCow
CashCow

Reputation: 31435

Now you have worked out how to use static class members I will advise you that you should generally use them only in the following circumstances:

  • For use in templates. So in your example you could have GetX() in different classes and in a template somewhere you would use

    template< typename T >
    int func()
    {
        return T::GetX();
    }
    

    although obviously more elaborate. But here your static function being in a class serves a purpose.

  • Where the function needs access to the class, i.e. to private members. You could make it a friend but you may as well make it static. Often the case in callbacks.

The rest of the time you can probably use compilation-unit level functions and variables which has the advantage of taking your members out of the header (particularly if they are private). The less implementation detail you give the better.

Upvotes: 1

Prasoon Saurav
Prasoon Saurav

Reputation: 92854

Section [9.4.2]

Static Data Members

The declaration of a static data member in its class definition is not a definition and may be of an incomplete type other than cv-qualified void. The definition for a static data member shall appear in a namespace scope enclosing the member’s class definition. In the definition at namespace scope, the name of the static data member shall be qualified by its class name using the :: operator

Upvotes: 14

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272467

The definition of static member variables must live at file scope, i.e. outside all functions, etc.

Upvotes: 3

Related Questions