初始化私有成员静态常量数组

Initializing private member static const array

本文关键字:常量 数组 静态 成员 初始化      更新时间:2023-10-16
class MyClass
{
public:
         ...
private:
    enum class BDTNodeType : unsigned char
    {
        NT_TERMINAL_ZERO,
        NT_TERMINAL_ONE,
        NT_TERMINAL_X,
        NT_NOT_TERMINAL
    };
    class BDTNode
    {
    public:
        explicit BDTNode(BDTNodeType node_type = BDTNodeType::NT_NOT_TERMINAL);
        BDTNode(const BDTNode &node);
        ~BDTNode();
        BDTNodeType type;
        BDTNode *thenPtr;   //1
        BDTNode *elsePtr;   //0
    };
    BDTNode *root_node;
    //Constant nodes
    static const BDTNode fv_nodes[3] = {
        BDTNode(BDTNodeType::NT_TERMINAL_ZERO),
        BDTNode(BDTNodeType::NT_TERMINAL_ONE),
        BDTNode(BDTNodeType::NT_TERMINAL_X)
    };
};

我想直接在类声明中初始化静态常量 BDTNode fv_nodes数组,因为 C++11 允许这样做。但是我得到"C2864:'MyClass::fv_nodes':具有类内初始值设定项的静态数据成员必须具有非易失常量积分"。而且我不能在类外初始化它,因为在这种情况下,"BDTNode"类将无法访问。那么我应该怎么做呢?

C++11允许这样做

不,C++11 不允许这样做。您可能正在考虑非静态成员初始化器,允许将其作为构造函数中初始化的替代方法。

对于静态成员,规则没有太大变化。类内声明不是定义,除非它是非易失性 const 整数或枚举类型并且未使用 odr,否则它需要在类外部使用单个定义。如果您提供初始化器,则继续定义。

而且我不能在类外初始化它,因为在这种情况下,"BDTNode"类将无法访问。

否,初始化器在类的范围内,因此可以访问私有名称。以下内容对我有用:

// in class
static const BDTNode fv_nodes[3];
// in a source file
const MyClass::BDTNode MyClass::fv_nodes[3] = {
    BDTNode(BDTNodeType::NT_TERMINAL_ZERO),
    BDTNode(BDTNodeType::NT_TERMINAL_ONE),
    BDTNode(BDTNodeType::NT_TERMINAL_X)
};

但是如果你愿意,你可以使用静态函数来做到这一点:

c++11 中确实发生了变化,因为它是线程安全的,无需显式使用互斥锁。

#include <array>
class MyClass
{
public:
    //    ...
private:
    enum class BDTNodeType : unsigned char
    {
        NT_TERMINAL_ZERO,
        NT_TERMINAL_ONE,
        NT_TERMINAL_X,
        NT_NOT_TERMINAL
    };
    class BDTNode
    {
    public:
        explicit BDTNode(BDTNodeType node_type = BDTNodeType::NT_NOT_TERMINAL);
        BDTNode(const BDTNode &node);
        ~BDTNode();
        BDTNodeType type;
        BDTNode *thenPtr;   //1
        BDTNode *elsePtr;   //0
    };
    BDTNode *root_node;
    static const std::array<BDTNode, 3>& fv_nodes() {
        static const std::array<BDTNode, 3> _fv_nodes {
            BDTNode(BDTNodeType::NT_TERMINAL_ZERO),
            BDTNode(BDTNodeType::NT_TERMINAL_ONE),
            BDTNode(BDTNodeType::NT_TERMINAL_X)
        };
        return _fv_nodes;
    }
    static const BDTNode& fv_node(size_t i) {
        assert(i < 3);
        return fv_nodes()[i];
    }
};