我是C 中的新手,我遇到了一个问题,我需要通过我的班级中的Typedef来定义新的数据类型。我班级的.H模块的相关代码片段正在遵循
class Manager
{
public:
static const uint8_t NO_BYTES_IN_PACKET;
static const uint8_t NO_PYLD_BYTES_IN_CONTROL_PACKET;
// control packet structure
typedef union{
struct{
uint8_t header[3];
uint8_t payload[NO_PYLD_BYTES_IN_CONTROL_PACKET];
}pkt_parts_t;
uint8_t pkt_array[NO_BYTES_IN_PACKET];
}control_pkt_u;
private:
}
我的问题是常数
static const uint8_t NO_BYTES_IN_PACKET;
static const uint8_t NO_PYLD_BYTES_IN_CONTROL_PACKET;
在相关的.cpp模块中定义
const uint8_t Manager::NO_BYTES_IN_PACKET = 8;
const uint8_t Manager::NO_PYLD_BYTES_IN_CONTROL_PACKET = 5;
因此,我一直在收到一条错误消息:错误:数组绑定在编译过程中']'']''我的想法是将工会定义转移到.cpp模块中,但我不确定这是否是正确的方法。您有什么意见?谢谢您的任何想法。
如果您不 odr-use 那些 static const int
,则无需在.cc文件中定义它们,只需将值放入.h文件中:
class Manager
{
public:
static const uint8_t NO_BYTES_IN_PACKET = 8;
static const uint8_t NO_PYLD_BYTES_IN_CONTROL_PACKET = 5;
/* .... */
};
但是,如果您使用这些常数,例如采用它们的地址,则需要在.cc文件中定义它们,则.h文件中的类定义保持不变:
const uint8_t Manager::NO_BYTES_IN_PACKET;
const uint8_t Manager::NO_PYLD_BYTES_IN_CONTROL_PACKET;
编辑:对于评论或其他答案,声称static const int
不能用作编译时常数,他们的主张是错误的。
以下引用来自[class.static.data]/3(强调矿山(:
如果非挥发性const静态数据成员是积分或枚举类型,则其在类定义中的声明可以指定一个brace-or-qual-Inialializer,其中每个(分配(表达的每个初始化器条件是常数表达式([Expr.Const](。可以使用ConstexPR规范的类别定义在类型中声明字面类型的静态数据成员;如果是这样,则其声明应指定一个支撑或平等限制器,其中每个初始化器子句(分配表达式(都是恒定的表达式。[注意:在这两种情况下,成员可能以常数表达方式出现。 - end Note] 如果它是ODR使用的,则成员仍应在名称空间范围中定义。([basic.def.odr](和命名空间范围定义不包含初始器。
问题是static const
并不意味着它是编译时间常数。作为不是什么地方,可能是程序开始的时间。
您想要的是constexpr
,它告诉编译器可以在编译器时间计算,这意味着您的数组大小已很好地定义,并且更清楚地传达了您的意图。
IE
class Manager{
public:
constexpr uint8_t NO_BYTES_IN_PACKET = 8;
...
另外;它将迫使您解决实际问题,即其他编译单元无法看到常数的大小,因为您未在标题中定义它。