初始化私有成员静态const数组

时间:2014-12-19 15:39:29

标签: c++ arrays c++11 initialization static-members

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)
    };
};

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

2 个答案:

答案 0 :(得分:6)

  

C ++ 11允许这样做

不,C ++ 11不允许这样做。您可能会想到非静态成员初始化程序,它们可以替代构造函数中的初始化。

对于静态成员,规则没有太大变化。类内声明不是定义,除非它是非易失性const积分或枚举类型而不是odr-used,否则它需要在类之外的单个定义。如果你提供了一个初始化者,那就是定义。

  

我无法在课外进行初始化,因为在那种情况下" BDTNode"班级将无法进入。

不,初始化程序属于类的范围,因此可以访问私有名称。以下works for me

// 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)
};

答案 1 :(得分:1)

但如果您愿意,可以使用静态函数执行此操作:

这个在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];
    }
};