The problem of accessing static constant variables through class member functions

I am having a problem accessing a static constant variable defined in the private private variable section. In particular, the code written below can output a variable inside a constructor, but when I try to access it via an accessor function, I get the error described below. If anyone knows why I would appreciate your help.

#include <iostream>
using namespace std;

class TestStaticVariables
{
 // Private member variable:
 static const double static_double_variable;
public:
 // Constructor:
 TestStaticVariables()
 {
  // Initialization:
  static const double static_double_variable = 20.0;
  cout << static_double_variable;
 }
 // Member Function:
 void test();
};

void TestStaticVariables::test()
{

      

When this next line is uncommented, I get the following error message:

Line Location Tool: 0: "TestStaticVariables :: static_double_variable" referenced by:

 //cout << static_double_variable;
}

int main(int argc, char* const argv[])
{

 TestStaticVariables test_instance;

 return 0;
}

      

+1


a source to share


4 answers


Try to initialize a variable outside of the class definition, here is a working example:



#include <iostream>

class Foo {
    static const double _bar;

public:
    Foo();

    void Bar();
};

const double Foo::_bar = 20.0;

Foo::Foo() {
    std::cout << Foo::_bar << std::endl;
}

void Foo::Bar() {
    std::cout << Foo::_bar << std::endl;
}

int main( int argc, char *argv[] ) {
    Foo f;
    f.Bar();

    return 0;
}

      

+9


a source


What you marked as "// Initialize" is actually the creation and initialization of a second variable with the same name in a different scope. A static_double_variable created inside a constructor is a local variable in the constructor and is not a class-level static variable of the same name.

What you need to do to avoid this is to simply remove the type information so that it is a normal assertion and not an initialization, e.g .:

   // Initialization:
   static_double_variable = 20.0;

      

But of course this won't work because this is a const variable assignment and you still have a second problem, which I think is actually causing the error you are seeing. When you write:

  // Private member variable:
 static const double static_double_variable;

      



You are stating that such a variable will exist. However, you are not actually defining this variable (i.e. instructing the compiler to create a repository for it).

To do this and fix both problems outside of your construct class { }

, you would write:

 const double  TestStaticVariables::static_double_variable = 20.0;

      

This defines the variable and gives it an initial, constant value.

If it is unclear, this question is also briefly described in the C ++ FAQ: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.10

+2


a source


What you are doing in the constructor is hiding the member variable.
You must initialize static_double_variable

outside of the class declaration.

+2


a source


Your constructor declares and defines a local static variable, which, as such, has the same name as the static member variable of the class. The local variable hides the class member.

This is what you can see in the constructor. Then, when you try to bind yourself to a class member in another method, the linker finds that it is declared but not defined, so it refuses.

You probably shouldn't initialize a static member of the class in the constructor, as there is only one variable for the class, but the constructor is called once for each instance. You must define the variable outside of any function (or just in the declaration if you don't want to hide the value from the users of your API).

+1


a source







All Articles