Static Member Variable in a Class

Static class member variable and static variable in c++

The only reason is code cleanliness. You cannot restrict access to a global static variable like

static int globalValue=5;

it is (at least) visible in the source file you defined it.
With a class static, you can give a user of your class hints, how you wish to access it or be accessed. It is only visible within the class scope:

class myGlobalContainer
{
public:
static int myInt;
protected:
static float myFloat;
private:
static bool myBool;
};

the access of myInt is done by:

int x=myGlobalContainer::myInt;

the public modifier gives the user the hint that you see this value as part of the myGlobalContainer and wish him to use it. You do not polute the global namespace like you do with the globalValue.

The modifier protected and private shows that you do not wish that an "outsider" access those values.

protected and private static attributes are mostly used to share information between the instances of a class, for e.g. a instance counter:

class myGlobalContainer
{
public:
myGlobalContainer()
{
if(counter==0)
DoSomeSpecialGlobalInit();
counter++;
}
~myGlobalContainer()
{
counter--;
if(counter==0)
DoSomeSpecialGlobalUnInit();
}
private:
static int counter=0;
};

public static attributes are often seen with const. They mostly give a user a shortcut. For e.g.:

COLOR white=COLOR::WHITE;

instead of:

COLOR white=COLOR::FromAGBR(255,255,255,255);

Add least:
If you should use statics or not is a complete other discussion.

How to declare and initialize a static member in a class?

One can definitely have class static members which are not CV-qualified (non const and not volatile). It is just that one should not initialize them (give them value) when one declare them inside the class, based on current ISO C++ regulations. In Comparison, it is OK to do so for non static data members(regardless of CV-qualification) Since C++11.

Because static data members do not belong to any object, with the right access they can be assigned (and if they are not constant, they can be manipulated) outside of the class(keeping in mind the right scope operator). Also regardless of public/private declaration and CV-qualification, static data members can be initialized outside their class.

So one way for initializing static data members, is to do so in the same block-scope/namespace where their classes(outer class in case of sub-classes) are situated, but not inside any class scope.

For example:

class Graph {
public:
class Node {
public:
static int maxNumberOfNeighbors;
.
.
.
};
.
.
.
};

int Graph::Node::maxNumberOfNeighbors = 4;
//also int Graph::Node::maxNumberOfNeighbors(4);

Good luck!

Static variable vs static member

Both samples cannot be compiled. What does the static Foo_instance mean? Did you mean static Foo instance?

Now back to your question: if you define the static variable inside of a function, it will be initialized only when you call the function for the first time. That has 2 consequences:

  • You will not spend resources if you never use this object;
  • If the constructor requires other resources to be allocated, you may need to control the time of creation. The time of creation of the static member is not defined.

Accessing static class variables in C++?

You must add the following line in the implementation file:

int Foo::bar = you_initial_value_here;

This is required so the compiler has a place for the static variable.

why i can't call a static member variable in an static member function like this?

How to solve it

Using C++17 you can inline the static variable which removes the need to define it outside the class.

static inline int i = 0; // I would also initialize it to zero, just to be sure 

If you cannot use C++17 you will have to define

int Test::b = 0; // Again I would also initialize it to zero, just to be sure 

outside of class Test

To the why

When you wrote

static void test()
{
static int b; // <-- definition is here
b = 3;
cout << b << endl;
}

you defined the function directly in the class (which means it is automatically marked inline). You then also have the definition of your static variable right there. If it is outside of the function scope, it is only a declaration (except if explicitly marked as inline - as shown above).

In contrast, in the other case it is outside of the function definition and hence your are missing the definition of the static variable.

class Test {
public:
static int b ; // <-- only declaration - definition is missing
static void test()
{
b = 3;
cout << b<<endl;
}
};

Fix spelled out for C++17

class Test {
public:
static inline int b = 0; // <-- now it is defined (and for safety initialized)
static void test()
{
b = 3;
cout << b<<endl;
}
};

Fix spelled out prior to C++17

#include <string>
#include <iostream>
using namespace std;
class Test {
public:
static int b; // declaration
static void test()
{
b = 3;
cout << b << endl;
}
};

int Test::b = 0; // definition

int main()
{
Test::test();

return 0;
}

Trouble initializing and incrementing a static member variable

The two errors in your code are:

  1. Your call to display_total_no_of_student() doesn't provide either a class object or a class name for that function, so the compiler is looking for a 'free' function of that name/signature, which it doesn't find.

  2. Although you have provided a declaration for the static count_total_no_of_students_enrolled member, you haven't given an actual definition for it (which must be done outside the class definition).

For the first issue, you would most likely want to declare display_total_no_of_student as a static function (because it doesn't use or require any specific instance of the Student class). For the second issue, just provide a definition of the count_total_no_of_students_enrolled member, which should be initialized to zero.

Here is a 'working' version of your code, with these issues addressed:

#include <iostream>

using namespace std;

class Student {
public:
string student_name;
double CGPA;
string degree;
static unsigned int count_total_no_of_students_enrolled; // This DECLARES the variable but doesn't define it!
const string uni_name = "umt";

void setstudent(string a, double b, string c);
void displaystudent();
static void display_total_no_of_student(); // Declare this function as static!
};

unsigned int Student::count_total_no_of_students_enrolled = 0; // This is the REQUIRED definition and initial value!

void Student::setstudent(string a, double b, string c)
{
student_name = a;
CGPA = b;
degree = c;

count_total_no_of_students_enrolled++; //******THIS ISN'T WORKING******
}

void Student::displaystudent()
{
cout << "\n=> Student details:\n";
cout << " Name: " << student_name << ",CGPA: " << CGPA << "\n Degree: " << degree << ",University: " << uni_name;
}

void Student::display_total_no_of_student()
{
cout << "\n Total Students Enrolled: " << count_total_no_of_students_enrolled;
}

int main()
{
Student s1, s2, s3;

s1.setstudent("John Doe", 3.5, "CS");
s2.setstudent("Jane Doe", 3.9, "CS");
s3.setstudent("Jim Doe", 3.8, "CA");

s1.displaystudent(); s2.displaystudent(); s3.displaystudent();

Student::display_total_no_of_student(); // Specify the class name to access a static member function!

return 0;
}

Please feel free to ask for any further clarification and/or explanation.

Singleton - Impl. using static class member vs. static member variable

When you put a static variable inside a function it is created the first time the function is called so it is guaranteed to have been instantiated to all callers of the function.

Members that are declared static could be instantiated before or after you call your function because the initialization order between translation units is undefined. So a global object or static object could try to access a static member before its been initialized by the runtime system.

So to your questions:

  1. Can we consider both impl. as a valid impl. of the design pattern?
  2. Are both, functionally, the same?

No. Using a static member is dangerous because a caller to SingletonCSM::GetInstance() can access a non-created object if the nullptr initialization has not taken place before the call. The static function method is the recommended method because it guarantees initialization has completed for every caller.

I just don't understand what was the problem and why was it solved?

In your case moving to the more dangerous method appears to have stopped your crash. I can not explain why that is. But you may not have removed the problem, it may be that you have undefined behavior elsewhere that has simply stopped manifesting in this case but that may resurface later with a different change.

Why do non-constant static variables need to be initialized outside the class?

Essentially it's because x exists independently of the number of instances of A that are created.

So storage for x needs to be defined somewhere - you can't rely on an instance of A to do that, and that's what

A::x = 0;

in exactly one translation unit, does.

Undefined reference to declared C++ static member variable

In C++, static variables are essentially syntactic sugar around global variables. Just like global variables, they must be defined in exactly one source file, with:

int Test::nb;

and if you want to initialize it with a particular value,

int Test::nb = 5; // or some other expression

Accessing private member variables of a class from a static method

static myClassPtr create(unsigned int val) {

create() is a static method of myClass, it is a member of this class. As such it it entitled to access all private members and methods of its class. This right extends not only to its own class instance, but any instance of this class.

As per my understanding private members should not be accessible.

... except by members of their class.

Let's create a completely pointless copy constructor for your class, the same copy constructor you would get by default:

myClass(const myClass &o) : m_val{o.m_val} {}

This copy constructor has no issues, whatsoever, of accessing m_val of the passed-in object. Exactly the same thing happens here. m_val is a private member of its class. It doesn't mean that only an instance of the same exact object can access its private members, it means that any instance of the class, or a static class method, can access the private class members.



Related Topics



Leave a reply



Submit