Reputation: 10868
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
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
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
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
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
Reputation: 88711
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
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
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
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
Reputation: 272467
The definition of static member variables must live at file scope, i.e. outside all functions, etc.
Upvotes: 3