Reputation: 5064
I am having a problem accessing a static const variable defined in my class private member variable section. Specifically, the code written below can output the variable within the constructor, but when I try to access it through an accessor function, I get an error discussed 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 from:
//cout << static_double_variable;
}
int main(int argc, char* const argv[])
{
TestStaticVariables test_instance;
return 0;
}
Upvotes: 1
Views: 4479
Reputation: 279245
Your constructor declares and defines a local static variable, which just so happens to have the same name as the class static member variable. The local variable hides the class member.
This is what you can see in the constructor. Then when you try to link against the class member in the other method, the linker discovers that it is declared but not defined, so it gives up.
You probably shouldn't initialize a static class member in a constructor anyway, since there is only one variable for the class, but the constructor is called once for each instance. You should define the variable outside any function (or just in the declaration, unless you want to conceal the value from users of your API).
Upvotes: 1
Reputation: 84159
What you are doing in the constructor is hiding the member variable.
You have to initialize the static_double_variable
outside of the class declaration.
Upvotes: 2
Reputation: 76660
What you have marked as "// Initialization" is actually a creating and initializing a second variable with the same name, in a different scope. The static_double_variable variable created inside the constructor is a local variable in the constructor, and does not refer to the class-level static variable with the same name.
What you need to do to avoid this is to simply remove the type information so that it's a normal statement rather than an initialization, like so:
// Initialization:
static_double_variable = 20.0;
But of course this won't actually work because it's an assignment to a const variable, and you still have a second problem, which is what I think is actually causing the error you see. When you write:
// Private member variable:
static const double static_double_variable;
You are declaring that such a variable will exist. However you are not actually defining that variable (i.e. instructing the compiler to create storage for it).
In order to do that, and fix both your issues outside of your class { }
construct, you would write:
const double TestStaticVariables::static_double_variable = 20.0;
This both defines the variable and gives it an initial, constant value.
In case that was unclear, this issue is also described succinctly in the C++ FAQ: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.10
Upvotes: 2
Reputation: 4693
Try initializing the variable outside 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;
}
Upvotes: 9