通过typedef定义C ++新类型

时间:2018-02-26 16:08:23

标签: c++ header-files typedef unions

我是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模块中,但我不确定它是否是正确的方法。你有什么看法?谢谢你的任何想法。

2 个答案:

答案 0 :(得分:2)

如果你没有使用那些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静态数据成员是整数类型或枚举类型,则其在类定义中的声明可以指定一个大括号或大小为初始化器,其中作为赋值表达式的每个initializer子句都是一个常量表达式([expr.const])。可以使用constexpr说明符在类定义中声明文字类型的静态数据成员;如果是这样,它的声明应指定一个大括号或等于初始化器,其中作为赋值表达式的每个initializer子句都是一个常量表达式。 [注意:在这两种情况下,成员可能会出现在常量表达式中。 - 结束注释] 如果成员使用了odr,则仍应在命名空间范围内定义程序中的([basic.def.odr])和命名空间范围定义不应包含初始化程序。

答案 1 :(得分:1)

问题在于static const并不意味着它是编译时常量。作为一个例子,它可能是程序开始的时间。

你想要的是constexpr告诉编译器它可以在编译器时计算,这意味着你的数组大小定义得很好,它可以更清楚地传达你的意图。

class Manager{
    public:
        constexpr uint8_t NO_BYTES_IN_PACKET = 8;
        ...

另外;它将迫使你解决真正的问题,即其他编译单元无法看到常量的大小,因为你没有在标题中定义它。