在.h文件包含在多个cpp文件中的类中定义整数静态const

ram*_*ram 0 c++ one-definition-rule visual-c++ language-extension

A.h

class A  
{  
   private:
     static const int b = 50;
     int c[b];
 };

 A.cpp

 #include "A.h"
 const int A::b;

 C.cpp

 #include "A.h"
Run Code Online (Sandbox Code Playgroud)

编译器向我发出警告,说b多次定义,一个被忽略.我需要在类中定义它,因为我需要初始化数组.或者,我需要使用枚举方法来做到这一点.但我想知道这是否可行?

Jam*_*lis 6

我猜你正在使用Visual C++,它有一个相当可怕的语言扩展,如"Microsoft C++和C++扩展"中所述:

Out of Class定义静态const Integral(或enum)成员

在standard(/Za)下,您需要为数据成员创建一个类外定义.例如,

class CMyClass {
    static const int max = 5;
    int m_array[max];
}
...
const int CMyClass::max;   // out of class definition
Run Code Online (Sandbox Code Playgroud)

根据/Ze,乱级的定义是可选的静态常量积分和常量枚举数据成员.只有静态和const的积分和枚举可以在类中包含初始化器; 初始化表达式必须是const表达式.

为了避免在提供类外定义时出错(当在头文件中提供了类外定义并且头文件包含在多个源文件中时),您应该使用selectany.例如:

__declspec(selectany) const int CMyClass::max = 5;
Run Code Online (Sandbox Code Playgroud)

/Ze默认情况下启用该标志./Za如果您不想使用语言扩展,则必须显式使用该标志.

使用带有/Za标志集的g ++ 4.5.2,Clang 3.0和Visual C++ 2010,编写的代码编译和链接没有错误.

如果要使用Visual C++进行编译,则从.cpp文件中删除定义可以解决问题,但/Za如果您尝试使用数据成员,则无法与其他编译器(或)一起使用.对于可移植的解决方法,您可以使用条件编译块来检查扩展是否已启用:

#ifndef _MSC_EXTENSIONS
const int A::b;
#endif
Run Code Online (Sandbox Code Playgroud)