Why is this "invalid C++"
I was reading intro on gtes开发者_运维问答t and found this part confusing:
The compiler complains about "undefined references" to some static const member variables, but I did define them in the class body. What's wrong?
If your class has a static data member:
// foo.h class Foo { ... static const int kBar = 100; };
You also need to define it outside of the class body in foo.cc:
const int Foo::kBar; // No initializer here.
Otherwise your code is invalid C++, and may break in unexpected ways. In particular, using it in Google Test comparison assertions (EXPECT_EQ, etc) will generate an "undefined reference" linker error.
Can somebody explain why defining a static const in in a class without defining it outside class body is illegal C++?
First things first, inside a class body is not a definition, it's a declaration. The declaration specifies the type and value of the constant, the definition reserves storage space. You might not need the storage space, for instance if you only use the value as a compile time constant. In this case your code is perfectly legal C++. But if you do something like pass the constant by reference, or make a pointer point to the constant then you are going to need the storage as well. In these cases you would get an 'undefined reference' error.
The standard basically states that even though you can give a value in the header, if the static variable is "used" you must still define it in the source file.
In this context "used" is generally understood to mean that some part of the program needs actual memory and/or an address of the variable.
Most likely the google test code takes the address of the variable at some point (or uses it in some other equivalent way).
Roughly: In the class definition, static const int kBar = 100;
tells the compiler "Foo will have a kBar constant (which I promise will always be 100)". However, the compiler doesn't know where that variable is yet. In the foo.cc file, the const int Foo::kBar;
tells the compiler "alright, make kBar in this spot". Otherwise, the linker goes looking for kBar, but can't find it anywhere.
精彩评论