static array class variable multiple definition C++
You're violating the one definition rule. Move the definition inside an implementation file:
//A.cpp
#include "A.h"
const int A::a[] = {1,2};
The solution you are reffering to, with extern
, applies to non-member variables. In your case a
is a class member.
linking error : multiple definition of static variable
So, this is a common mistake of misunderstanding how the header guards work.
Header guards save multiple declarations for one compilation unit, but not from errors during linking. One compilation unit implies a single cpp file.
E.g. apple.cpp includes apple.h and grapes.h, and apple.h in turn includes grapes.h. Then header guards will prevent the inclusion of the file grapes.h again during compilation.
But when the process of compilation is over, and the linker is doing its job of linking the files together, then in that case it sees two memory locations for the same static variables, since the header file was included in a separate translation unit, say apple2.cpp to which its trying to link, thus causing the multiple definition error.
The only way to resolve it is to move the definition of the static variable to a cpp file.
Multiple definition error on variable that is declared and defined in header file and used only in its cpp file
If you declare your variable in the header file:
#ifndef GLOBAL_H
#define GLOBAL_H
int foo = 0;
#endif
In every include of your header file or translation unit, a new instance of your integer is created. As you mentioned, to avoid this, you need to declare the item as "extern" in the header file and initialize it in the implementation file:
// .h
extern int foo;
// .cpp
int foo = 0
A more C++ way to do that can be something like this:
#ifndef GLOBAL_H
#define GLOBAL_H
struct Global {
static int foo;
};
#endif
And in your cpp file:
#include "variables.h"
int Global::foo = 0;
C++17 fixes this problem with inline variables, so you can do:
#ifndef GLOBAL_H
#define GLOBAL_H
inline int foo = 0;
#endif
See How do inline variables work? for more information.
C++ Error : multiple definition of class_name::class_name()
This code:
B::B(){//some code};
B::~B(){//some code};
Will be pasted by the pre-processor into multiple translation units (A.cpp
and main.cpp
). It will be compiled 2 times and therefore violates the ODR (One definition rule). If you implemented it in the class:
class B
{
B() { ... }
Then it would be automatically inlined, avoiding this issue. Since you have it out of the class you need to tell the compiler and the linker that you intended this using the inline
keyword:
inline B::B(){//some code};
inline B::~B(){//some code};
Read more about the inline
keyword here.
how to use class static variable across files
Create another translation unit Body.cpp
and move the definition there
int Body::i=2;
Even with header guards, as you mention to have them, the definition appears in multiple translation units, hence the multiple definition error.
In your particular case the static
class member is a primitive, and can be initialized at the point of declaration alternatively:
class Body {
static int i = 2;
};
Related Topics
Is a Struct's Address the Same as Its First Member's Address
C++ Map Access Discards Qualifiers (Const)
How to Use 'Const_Cast' to Modify a Constant Variable
If a 32-Bit Integer Overflows, How to Use a 40-Bit Structure Instead of a 64-Bit Long One
How to Require an Exact Function Signature in the Detection Idiom
How to Convert a Time into Epoch Time
What Is Vc++ Doing When Packing Bitfields
Increase Stack Size When Compiling with Mingw
Compiling Code Containing Dynamic Parallelism Fails
To Stl or !Stl, That Is the Question
Calculating Execution Time in C++
How to Log Stack Frames with Windows X64
Rodrigues into Eulerangles and Vice Versa
C++ Passing an Array Pointer as a Function Argument
In C++, Can a Class with a Const Data Member Not Have a Copy Assignment Operator