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

时间:2011-04-09 02:03:42

标签: c++ visual-c++ language-extension one-definition-rule

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"

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

2 个答案:

答案 0 :(得分:6)

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

  

静态const积分(或枚举)成员的类定义

     

在标准(/Za)下,您需要为数据成员制定一个类外定义。例如,

class CMyClass {
    static const int max = 5;
    int m_array[max];
}
...
const int CMyClass::max;   // out of class definition
     

/Ze下,对于static,const integral和const enum数据成员,out-class-class定义是可选的。只有静态和const的积分和枚举可以在类中包含初始化器;初始化表达式必须是const表达式。

     

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

__declspec(selectany) const int CMyClass::max = 5;

默认情况下启用/Ze标志。如果您不想使用语言扩展名,则必须明确使用/Za标志。

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

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

#ifndef _MSC_EXTENSIONS
const int A::b;
#endif

答案 1 :(得分:0)

你给出了相互矛盾的定义。通过在类定义中赋予变量值,您可以说它是一个不需要任何存储的编译时常量。然后你试图将它存储在.cpp文件中。

把它从.cpp中拿出来你就没事了。只是不要试图取其地址。