Yves
Yves

Reputation: 12381

Is it possible to initialize a static member variable after running the main?

Test.h

class Test
{
    static int i;
};

Test.cpp

int Test::i = 1;

I know that normally we initialize a static member as above. And the static member is initialized before the function main runs.
My question is:
Is it possible to initialize the static member after the function main runs? Something like this:

int main()
{
// do something
// initialize the Test::i here
}

Upvotes: 3

Views: 180

Answers (4)

anakin
anakin

Reputation: 589

The first mistake you have is that the variable 'i' is private for the class, so you cannot access it outside the class. There are two ways to fix this. The first is to make it public(not preffered) and the second to make setter and getter methods.

About the question the answer is yes, you can. Use the setter method I mentioned above. These are the two methods:

//…
public:
  static int get_i() {
    return i;
  }
  static void set_i(int val) {
    i = val;
  }
//…

You can call the method like that:

Test::set_i(10);

Note: do not forget to include the keyword public before the methods so you can access them outside the class.

Upvotes: 0

Mekap
Mekap

Reputation: 2085

You're confusing the word static and the word const.

You have to initialize a const when you declare it;

You don't have to initialize a static when you declare it, but you can change it anywhere anytime, given you can access it. (which is not the case here, your i is private.)

About thoses statements, let's look at the C++ standard (3.6.2) :

Variables with static storage duration or thread storage duration shall be zero-initialized before any other initialization takes place.

Technically, yes, your static data is always zero-initialized even if you explicitely initialize it.

Upvotes: -1

Wintermute
Wintermute

Reputation: 44063

I'm going to assume that you really mean initialization, so that assignment after main has started is out. This will not make a difference for basic types like int or double, but may make one for complex data types.

The answer is: no but yes (sort of). It is not possible to delay the initialisation of a static data member until after main started, but you can use a static member function with a function-local static object to simulate the effect. This object will be initialized after the function is first called. In code:

#include <iostream>

struct A {
  A() {
    std::cout << "A::A()\n";
  }

  void do_something() {
    std::cout << "A::do_something()\n";
  }
};

struct B {
  static A &a() {
    static A instance;
    return instance;
  }
};

int main() {
  std::cout << "main start\n";

  B::a().do_something();
  B::a().do_something();

  std::cout << "main end\n";
}

This will print

main start
A::A()
A::do_something()
A::do_something()
main end

You would then use B::a() where you'd have used B::a before. You will have to make sure that the function is not called before main is started.

Upvotes: 1

Lundin
Lundin

Reputation: 214300

No, it isn't possible to initialize it, but there should be no reason why you can't just call a static setter function that assigns a value to i in run-time. This is the best method.

Or you alternatively, you could make it so that the constructor always initializes the variable:

#include <iostream>

class Test
{
  private:
    static int i;

  public:
    Test()
    {
      i=2;
    }

    void print_i (void)
    {
      std::cout << i << std::endl;
    }
};

int Test::i = 1;


int main()
{
  Test test;

  test.print_i(); // will print 2
}

Upvotes: 1

Related Questions