Is this the proper way to use a static const variable? In my top level class (Shape)
#ifndef SHAPE_H
#define SHAPE_H
class Shape
{
public:
static const double pi;
private:
double originX;
double originY;
};
const double Shape::pi = 3.14159265;
#endif
And then later in a class that extends Shape, I use Shape::pi. I get a linker error. I moved the const double Shape::pi = 3.14... to the Shape.cpp file and my program then compiles. Why does that happen? thanks.
It happens because you can't define Shape::pi more than once. It's defined once when you include Shape.h in Shape.cpp, and then again every other time you use Shape.h in another cpp file. When you go to link you program together the linker will barf because of multiple definitions.
Because
const double Shape::pi = 3.14159265;
is the definition ofShape::pi
and C++ only allows a single definition of a symbol (called the one-definition-rule which you may see in it's acronym form ODR). When the definition is in the header file, each translation unit gets it's own definition which breaks that rule.By moving it into the source file, you get only a single definition.
For primitive data types (like int, double but not char[]) you may also define the constant within the class definition within the header file, e.g.:
This will allow better compiler optimisation.
Edit: As Dennis pointed out below this is only allowed for integral types and not for double or float data types (however some compilers will allow it).
Static floating-point data members must be defined and initialized in a source file. The one-definition rule forbids a definition outside the
class {}
block in the header, and only integral data members are allowed to be initialized inside theclass {}
block.This is also unfortunate because, being an algebraic value, having the immediate value on hand could be nice for optimization, rather than loading from a global variable. (The difference is likely to be inconsequential, though.)
There is a solution, though!
Inline function definitions, including static ones, are allowed inside the
class{}
block.Also, I recommend using
M_PI
from<math.h>
, which you should also get from<cmath>
.If you have a way to add
C++0x
flag to your compiler, you would've been able to do:In
C++0x
you are able to use const expressions to types other than integral ones. This enables you to declare and define in place your constant variable.Implement a function that returns the index of a value to the list if it exists. Otherwise return -1 if there is no value. If the same value exists more than once on the list then the first value is deleted from the bottom.