Alex Rivera | Logout

Static const double in c++

Asked 2010-05-05T23:55:46.963
11

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.

Edit
Report

3 Answers

12

Because const double Shape::pi = 3.14159265; is the definition of Shape::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.

answered 2010-05-05T23:58:51.533
12

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 the class {} 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!

class Shape
{
public:
    static double pi()
        { return 3.14159265; }

private:
    double originX;
    double originY;
};

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>.

answered 2010-05-06T03:33:05.350
0

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.:

class Shape
{
public:
    static const double pi = 3.14159265;

private:
    double originX;
    double originY;
};

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).

answered 2010-05-06T07:43:37.100

Your Answer