C++ - 在另一个 header 文件中包含一个 header 文件以使全局变量可用于数组声明

C++ - Including one header file inside another header file to make global variables available for array declaration

我有一个名为 WorldState 的 class,我想在其中声明一个名为 covar_matrix[dim][dim] 的多维数组。全局变量dimint类型,在global.hglobal.cpp内部声明和定义。以下是 WorldState.h 的内容:

#ifndef WORLDSTATE_H
#define WORLDSTATE_H
#include "global.h"

class WorldState{

    public:
        WorldState(float [], float [][dim]);
        get_wstate();


    protected:

    private:
        float w_state[];
        float covar_matrix[][dim];

};

#endif // WORLDSTATE_H

将一个 header (global.h) 包含在另一个 (WorldState.h) 中是好的做法吗?

它仍然抛出错误:

||=== Build: Debug in slam (compiler: GNU GCC Compiler) ===|
C:\Users\syamp\Documents\codeblocks\slam\WorldState.h|8|error: array bound is not an integer constant before ']' token|
C:\Users\syamp\Documents\codeblocks\slam\WorldState.h|16|error: array bound is not an integer constant before ']' token|

如何在不通过构造函数传递任何大小的情况下声明此多维数组?

编辑: global.h的内容:

#ifndef GLOBAL_H_INCLUDED
#define GLOBAL_H_INCLUDED

extern int marker_num;
extern constexpr int dim;

#endif // GLOBAL_H_INCLUDED

global.cpp :

#include <iostream>
#include <cstdio>
#include <cmath>
#include "WorldState.h"
#include "Robot.h"
#include "Sensor.h"
#include "Marker.h"
#include "global.h"

int marker_num = 10;
constexpr int dim = (2 * marker_num) + 3;

数组维度不允许是任意变量。您需要用常量替换 dim

C++ 中的数组维度必须是 compile-time 常量。一个变量(即使声明为 const)是不够的。在 C++11 之前,您需要使用 constexpr(C++11 及更高版本)或文字值(如 100)。如果您想为维度命名,可以在 C++11 之前使用宏(如 #define DIM 100)。

没有什么可以阻止一个 header 包括另一个 - 预处理器只是进行文本替换,因此 #include 指令字面上被替换 (copy/paste) header。如果这是递归完成的(header A including header B which includes header A)有必要使用像 include guards 这样的机制来阻止递归变得无限(这往往会使预处理器扼流圈)。

您应该在 header:

中像这样声明您的 'dim' 变量
extern const int dimm;

没有 constexpr 限定符。然后在 global.cpp 中你可以像这样实例化它:

constexpr const int dimm = 5;

或者像这样:

const int dimm = 5;

两者都可以,因为编译器能够意识到第二个是隐式 constexpr。

如果您要计算同一语句中的值,则只能使用 constexpr 限定符。 但是,对于您手头的特定问题,我建议使用枚举:

enum {
    dimm = 5
};

枚举是纯粹的编译时常量,在 运行 时不占用 space(如果你不为任何变量分配值),并且在 header秒。该特定枚举是匿名枚举,这意味着它没有名称,只有一个值 dimm。

我发现最简单的事情是:

#ifndef GLOBAL_H_INCLUDED
#define GLOBAL_H_INCLUDED

static constexpr const int marker_num = 10;
static constexpr const int dim = (2 * marker_num) + 3;

using namespace std;

#endif // GLOBAL_H_INCLUDED

这是 link 我收到的答案:

我真的希望你看到这个并且没有继续你的生活。

在 header 中定义常量数据并在整个应用程序中使用它绝对是一个好习惯。同样的事情也适用于您在整个应用程序中使用的一些静态函数;你可以创建一个 Utility.h header 并存储你的实用函数(打印一些东西,你通常使用的数学公式等)并在任何地方使用 header。在您的其他 header 中包含您自己的 header 与包含其他人(例如 #include <iostream>)编写的 header 没有什么不同。

我个人不喜欢 constexpr 但我也没有有效的论据反对它,只是一个偏好。对我来说,#define 是一个更通用的东西,几乎意味着 static constexpr const。当您使用 #define 时,您基本上是在告诉编译器将粘贴定义的值复制到它使用的位置。示例:

#define MAX_NUMBER 10
...

int cityLimit = MAX_NUMBER * 2;

编译器将 MAX_NUMBER 与您放在它旁边的任何内容进行交换。简直就是复制粘贴。

这里有一个问题,不要在代码中使用 using namespace std(尤其是在全局声明或实用程序 header 中)。 using namespace std 从字面上获取整个命名空间内容并将其粘贴到它看到的任何地方。它会导致各种问题,它完全是命名空间系统,尤其是在较大的代码库中,它有时会让其他开发人员讨厌你。

大多数时候,人们使用 using namespace std 来加快 std::coutstd::endl 的书写速度。为此,您可以将 using namespace std; 更改为

using std::cout;
using std::endl;

它做同样的事情,但只从命名空间中获取那些函数,而不是其中的所有内容。