3

I think is an old question but I don't get it.

I have a header routines.h, its functions file routines.cpp and the main file main.cpp.

In the header there is:

class myclass{
public:
static const double a;
void mymethod();
};

const double myclass::a=0.0;

The routines.cpp contains: #include"routines.h" and then define the methods.

main.cpp also has #include"routines.h".

This setup gives a link error: a it's already defined.

public: static double const myclass::a" (?a148@myclass@@2NB) already defined in DBFLOWPAR2.obj

DBFLOWPAR2 is my main file.

If I define the methods in routines.h it works fine, but I don't like that. What else it's possible? I don't care how the variables are defined, I just want to be able to access myclass.a and find the right value in it.

MarcoS
  • 160
  • 7

4 Answers4

4

You should define the static variable in a cpp file.
Move,

 const double myclass::a=0.0;

to your cpp file.

Defining a in header file creates a copy of the variable in each Translation Unit where the header is included.

Community
  • 1
  • 1
Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • All right, thanks. First to answer so I'll accept this one. Just curious: isn't the macro `#ifndef Blala #define Blala #endif` supposed to avoid that? – MarcoS Mar 01 '12 at 16:34
  • @MarcoS: no. Include guards prevent the definition from appearing multiple times *in the same translation unit*. They don't stop different translation units (.cpp files) from each including the header file and hence the definition. – Steve Jessop Mar 01 '12 at 16:39
  • @MarcoS Include guards prevent a header from being included multiple times in a single translation unit. Your problem is that `const double myclass::a=0.0;` is occurring multiple times in a single _program_, which is made up of multiple translation units. I think a good exercise for understanding C++'s build model is to write some programs without using header files. Just manually 'include' the declarations and definitions you need. See what happens when you; duplicate a class definition in a single TU, put a function def in more than one TU, put a variable def in more than one TU. – bames53 Mar 01 '12 at 16:51
  • Just FMI is the `=0.0` part necessary? – Luchian Grigore Mar 01 '12 at 18:57
  • @LuchianGrigore: No, it is not, static variables are Zero Initialized. – Alok Save Mar 02 '12 at 02:42
  • Since I plan to use multithread, should I remove `static` ? What is now defined as `static const` is not supposed to change amongst threads. – MarcoS Mar 02 '12 at 10:19
  • @MarcoS: If you plan to use a global or a static in multithreaded envrionment then you will have to provide some synchronization, if the variable will be written and read accross multiple threads. About, `const`: Once you specify `const` any attempt to change the variable after initialization will result in incorrect program. – Alok Save Mar 02 '12 at 10:28
3

You have violated the One Definition Rule. Because you #include "routines.h" in multiple files, the definition of myclass::a appears in multiple files.

You must define a variable once, and only once.

Choose a convenient .cpp file, and move your definition to that .cpp.

Robᵩ
  • 163,533
  • 20
  • 239
  • 308
1

MyClass.h

class myclass{
public:
   static const double a;
   void mymethod();
};

MyClass.cpp

const double myclass::a;

The way you have it now, you're redefining myclass::a in every translation unit that includes the header.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
0

Don't put const double myclass::a=0.0; in the header file, otherwise each compilation unit including this file will have it's own separate variable. put this to routines.cpp.

Karoly Horvath
  • 94,607
  • 11
  • 117
  • 176