Static Array Class Variable "Multiple Definition" C++

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



Leave a reply



Submit