如何在 C++ 类中创建 const 数组和计算 const 值?
Posted
技术标签:
【中文标题】如何在 C++ 类中创建 const 数组和计算 const 值?【英文标题】:How do I create const arrays and calculated const values in C++ class? 【发布时间】:2009-05-14 15:44:26 【问题描述】:我遇到了一些我不理解的编译器错误。我很确定我在这里做错了什么,但我不知道是什么。我希望将所有世界常量定义为属于该类。
注意事项:
我只使用类作为带有附加成员的结构。我不是故意遵循严格的面向对象设计。请不要评论公共变量。
我不太关心编译器内联的东西。我使用这种结构是因为它易于使用。 (如果有效)
class Board
public:
enum PhysicsResult BOUNCE, OUT_OF_BOUNDS_TOP, OUT_OF_BOUNDS_BOTTOM, CONTINUE ;
//World constants
const static float Height = 500;
const static float Width = 300;
//ERROR: 'Board::Width' cannot appear in a constant-expression.
const static float PaddleWidth = Width/15;
const static float BallRadius = 5;
const static float BounceDistance = 1.5;
//World Objects
Ball ball;
Paddle paddle1;
Paddle paddle2;
/*
1---2
| |
0---3
*/
//ERROR: a brace-enclosed initalizer is not allowed here before '' token
//ERROR: invalid in-class initalization of static data member of nonintegral type 'const Pair[4]'
const static Pair corners[4] = Pair(0, 0), Pair(0, Height), Pair(Width, Height), Pair(Width, 0);
//ERROR: a brace-enclosed initalizer is not allowed here before '' token
//ERROR: invalid in-class initalization of static data member of nonintegral type 'const Pair[2]'
const static Pair left_wall[2] = corners[0], corners[1];
//ERROR: a brace-enclosed initalizer is not allowed here before '' token
//ERROR: invalid in-class initalization of static data member of nonintegral type 'const Pair[2]'
const static Pair right_wall[2] = corners[3], corners[2];
//ERROR: a brace-enclosed initalizer is not allowed here before '' token
//ERROR: invalid in-class initalization of static data member of nonintegral type 'const Pair[2]'
const static Pair top_wall[2] = corners[1], corners[2];
//ERROR: a brace-enclosed initalizer is not allowed here before '' token
//ERROR: invalid in-class initalization of static data member of nonintegral type 'const Pair[2]'
const static Pair bottom_wall[2] = corners[0], corners[3];
如果可以这样做,那么正确的语法是什么? 如果这不可能,我应该使用什么替代方法?
【问题讨论】:
【参考方案1】:在类的主体之外定义静态常量,使用 gcc 编译和执行。
#include <iostream>
using namespace std;
struct Pair int a; int b; Pair(int x, int y) : a(x),b(y) ;
struct F
static const float blah = 200.0;
static const Pair corners[4];
;
// square boards are so ordinary
const Pair F::corners[4] = Pair(0,0), Pair(0,1), Pair(2,0), Pair(2,2) ;
const float F::blah ;
int main(int, char **)
cout << F::corners[0].a << endl ;
cout << F::blah << endl;
return 0;
ebo 关于初始化顺序的评论的重要性怎么强调都不为过。
【讨论】:
您可能需要解决[静态初始化顺序问题][1] [1]:parashift.com/c++-faq-lite/ctors.html#faq-10.13 只要把它们放在同一个文件中,它们就会按顺序初始化。 我担心董事会将在一个文件(board.cpp)中,董事会用户将在另一个文件(game.cpp)中,会有Game的静态成员引用Board 的角落,并且根据 board.obj 和 game.obj 链接的顺序,程序将神秘地运行或崩溃。 如果你必须从其他翻译单元访问 F::corners,你也可以去掉 Pair 构造函数,像 const Pair F::corners[4] = 0, 0 , 0, 1 , ..... ;对象将在任何其他初始化发生之前初始化,然后直接在所有内容的零初始化之后进行(静态初始化。重要的是所有初始化表达式必须是常量表达式,并且数组是 POD 类型)。然后,您可以在运行时初始化的代码中安全地访问它(动态初始化) Thomas:对我的应用程序来说不是问题。 Paddle、Board 和 Ball 是代码中唯一的“对象”。其他一切都在全局函数中。我正在为程序的图形使用 OpenGL,所以我跳过了这个项目的 OOP。【参考方案2】:您必须在构造函数初始化列表中初始化 const 成员。
class blah
public:
blah() : _constant( 1 )
private:
const int _constant;
;
【讨论】:
什么是“构造函数初始化列表”? parashift.com/c++-faq-lite/ctors.html#faq-10.6 初始化器列表是您在成员上调用构造函数的方式。在上面的例子中,它是 ":_constant(1)" 部分。如果您需要多个,请用逗号分隔它们。即 blah() : _constant(1)、_constant1(2)、_constant2(3) 等... @mgb:不幸的是,没有办法使用初始化列表来初始化静态数据。此外,以下划线开头的标识符通常是不好的做法。我认为在这种情况下没关系,因为它后面跟着一个小写字母,但这仍然不是最佳实践,尤其是在 C++ 新手的示例中。见***.com/questions/228783/… 这会因 const 静态变量而失败。【参考方案3】:C++ 对象的静态成员需要在声明之外定义。这是因为编译器不知道将成员放入哪个翻译单元(.o 文件)。
通常我会在实现的 .cpp 文件中定义它们。您通常不希望将它们放入头文件中,因为它们最终会出现在多个 .o 文件中,并且会产生编译器错误,因为多次定义了相同的东西。
【讨论】:
很高兴知道未来。我现在将所有代码都放在标题中。以上是关于如何在 C++ 类中创建 const 数组和计算 const 值?的主要内容,如果未能解决你的问题,请参考以下文章