Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

static array class variable "multiple definition" C++

I'm writing some code where I need to have a class variable that's a static int array. I understand that I can do this with something like this in the header file, A.h:

#ifndef A_H_
#define A_H_

class A
{
public:
  static const int a[];
};

const int A::a[] = {1,2};

#endif

This works just fine if I'm then including this header in only one other file, something like the following, main.cpp:

#include "A.h"

#include <iostream>
using namespace std;

int main()
{

  A myA;  
  cout << "0: " << myA.a[0] << endl;
  cout << "1: " << myA.a[1] << endl;
}

But suppose I need my class A to be a bit more complicated, and I want to have an A.cpp file as well. I'll keep my main.cpp file the same, but then change A.h as follows (I've just added a function, printA):

#ifndef A_H_
#define A_H_

class A
{
public:
  void printA() const;
  static const int a[];
};

const int A::a[] = {1,2};

#endif

And then in file A.cpp:

#include "A.h"

#include <iostream>
using namespace std;

void A::printA() const
{

  cout << "Printing in A.cpp." << endl;
  cout << "A.0: " << a[0] << endl;
  cout << "A.1: " << a[1] << endl;

}

Compiling A.o with gcc -o A.o -c A.cpp is fine. But linking this when compiling main.cpp (gcc -o atest main.cpp A.o) fails with "multiple definition of `A::a'".

I've been scouring the internet for solutions, and found people who have variables declared in their headers who get the "multiple definition" error when they include the header in multiple places, and the solution seems to be to declare the variable extern in the header, then define it in only one source (non-header) source file. But I can't declare a class variable both static and extern, can I? If I try, or if I just declare it extern, I get a warning about the variable not being static (also a "conflicting specifiers" error when I try both).

So, my question: is it possible to have static array class variables in the case that the header file needs to be included in more than one source file? If so, how?

like image 499
rainbowgoblin Avatar asked May 23 '12 14:05

rainbowgoblin


2 Answers

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.

like image 111
Luchian Grigore Avatar answered Oct 07 '22 03:10

Luchian Grigore


You should remove the "const int A::a[] = {1,2};" line from the header file. Put this definition line in one of you .cpp files. Then you can include the header file several times where you need it.

like image 43
Xiaokun Zheng Avatar answered Oct 07 '22 04:10

Xiaokun Zheng