C++中的静态数组类变量“多重定义”问题

6

我正在编写一些代码,需要一个类变量作为静态整数数组。我知道可以在头文件A.h中使用以下代码实现:

#ifndef A_H_
#define A_H_

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

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

#endif

如果我只在一个其他文件中包含此头文件,类似于以下内容的 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;
}

但是假设我需要让我的A类变得更加复杂,我想要有一个A.cpp文件。我会保持我的main.cpp文件不变,然后按照以下方式更改A.h(我只是添加了一个函数printA):

#ifndef A_H_
#define A_H_

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

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

#endif

接着在文件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;

}

用gcc -o A.o -c A.cpp编译A.o是可以的。但是在编译main.cpp时进行链接(gcc -o atest main.cpp A.o)会出现“multiple definition of `A::a'”错误。
我一直在网上寻找解决方案,发现有些人在头文件中声明变量,当他们在多个地方包含头文件时,会出现“multiple definition”的错误。解决方法似乎是在头文件中声明变量为extern,然后只在一个源(非头)文件中定义它。但如果我尝试将类变量同时声明为static和extern,或者只声明为extern,我会得到一个关于变量不是静态的警告(也会在尝试两者时出现“conflicting specifiers”错误)。
所以,我的问题是:如果需要在多个源文件中包含头文件,是否可能拥有静态数组类变量?如果可以,怎么做?
2个回答

20

你正在违反单一定义规则。将定义移动到实现文件中:

//A.cpp
#include "A.h"
const int A::a[] = {1,2};
你所提到的解决方案,使用 extern 关键字,适用于非成员变量。在你的情况下, a 是一个类成员。

7
你应该从头文件中删除"const int A::a[] = {1,2};"这一行。将此定义行放在你的 .cpp 文件之一中。 然后你可以在需要的地方多次包含头文件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接