C++ 数组大小的静态常量成员
MyClass.hC++ 数组大小的静态常量成员,c++,C++,MyClass.h class MyClass { public: static const int cTotalCars; private: int m_Cars[cTotalCars]; }; MyClass.cpp #include "MyClass.h" const int MyClass::cTotalCars = 5; 上面的代码不起作用,因为它将为m_Cars数组显示“预期常量表达式” class MyClass { public: static const int c
class MyClass
{
public:
static const int cTotalCars;
private:
int m_Cars[cTotalCars];
};
MyClass.cpp
#include "MyClass.h"
const int MyClass::cTotalCars = 5;
上面的代码不起作用,因为它将为m_Cars数组显示“预期常量表达式”
class MyClass
{
public:
static const int cTotalCars = 5;
private:
int m_Cars[cTotalCars];
};
上面的方法会起作用,但是我被告知我应该总是在CPP文件中定义静态成员,而不是在类定义之外。我能做什么?我宁愿使用
#定义C#u总车数5
,然后静态常数int cTotalCars=C#u总车数然后,int m_Cars[C_TOTAL_Cars]代码>简单类型的静态常量成员是该规则的一个例外,因此后面的代码是正确的
这个例外是一个相当现代的例外(从C++98开始,但直到几年后才被每个编译器实现),所以许多老式的教师还没有意识到它。他们更喜欢这个成语:
class MyClass
{
public:
enum { cTotalCars = 5 };
private:
int m_Cars[cTotalCars];
};
它的行为完全相同,但在当今意义不大。如果它是一个静态int
,则需要将其放入.cpp文件中。在本例中,您不需要关键字static
,因为您只需要一个常量。只需使用const int cTotalCars=5代码>。它比#define
更好,因为您有类型信息,而且它还有一个可以在调试器中查看的符号
上面的方法会起作用,但是我被告知我应该总是在CPP文件中定义静态成员,而不是在类定义之外。我能做什么
那么,建议您做的是:在CPP中定义静态成员。请注意,在上面的代码中,静态成员未定义,即使声明了值。正确的最终代码如下所示:
// .h (ignoring all but the static member)
class MyClass {
static const int cTotalCars = 5; // declaration and initialization
};
// .cpp
static const int MyClass::cTotalCars; // definition (cannot have value!)
.cpp文件中的定义实际上是在用作左值时为变量保留空间的定义。对于验证没有该行变量未定义的简单测试,您可以执行以下操作:
void f( const int & x ) {}
int main() {
f( MyClass::cTotalCars );
}
如果.cpp文件中没有该行,上述代码将触发链接器错误,指向缺少的MyClass::cTotalCars
定义。代码的问题在于它使用了static const成员(根据标准中的use定义),这需要定义该成员。而使用常量定义数组大小的情况并不构成使用。如果在cpp文件中设置了定义数组大小,则无法使用。所有类客户机都应该知道类实例的大小,但他们只是不知道.cpp文件,因为您只在客户机文件中添加了#include“MyClass.h”
换句话说,根据使用MyClass编译文件时未使用的cpp文件,您的类定义会有所不同。为什么?为什么要放弃范围的好处而一无所获?@Geoffroy如果它有效,那么它回答了“我能做什么?”的问题,从而回答了这个问题。现在,我的C++可能是非常过时的(虽然GMan的意思是:D)你的解决方案是有效的,但是问题是关于静态成员。OP已经给出了一个有效的解决方案:)@Geoffroy这并不是我对这个问题的理解。现在,我读得越多,就越同意你的观点……:)“简单类型的静态常量成员是该规则的例外”不正确。您可能指的是整型而不是简单型,但即使使用整型常量,如果根据语言使用静态成员,也必须定义静态成员,这大致意味着用作左值(大致取其地址)。对于需要该定义的简单示例,请考虑:void f(const int&);f(MyClass::cTotalCars)代码>后一段代码的问题是,当我更改值并重新生成时,当其他类访问它时,它不会被更新。它们仍然具有旧的价值。进行干净的重建可以解决问题,但我不知道为什么。如果我使用以前的代码,则会出现数组问题,但当从外部类访问时,如果没有干净的构建,则会更新该值。@DavidRodríguez dribeas,因为您对积分的看法是正确的。GCC也允许像那样使用float
,但我没有注意到它是一个扩展。关于将变量用作左值,您当然也是对的。@user987280但这是您的编译系统的一个问题,它没有正确地检查对头文件的依赖性。如果您更改(比如)内联函数或枚举值,也会发生同样的情况。谢谢您提供的信息。我永远不需要得到这个变量的地址,也不需要将它用作引用,但这很好。我更感兴趣的是我刚才在罗德里戈的文章《repsonse》中描述的一个问题,即在使用我的后一个代码时,在重建后没有更新值。@user987280:您的问题不在于语言,而在于构建系统。依赖项没有在代码库中正确设置,因此,并非所有应该重建的内容都实际重建。花点时间修复构建系统并确保所有依赖项都正确。我不确定我是否理解。我要寻找什么类型的依赖关系?您能举一个您正在描述的例子吗?@user987280:如果更改头中的常量没有触发使用该常量的所有代码的重建,那么问题在于生成系统没有跟踪使用是否依赖于头(或者那些将自动重新编译),这就是你应该解决的问题。哦,好吧,我明白你的意思。除了查看VS build设置之外,我不知道如何进行修复,但我在那里没有看到任何东西。我只是在另一个cpp文件中复制了另一个类中的行为,所以至少它是一致的。