修复static const std :: string member []初始化

时间:2013-08-30 12:22:38

标签: c++ arrays static initialization const

此主题可能已经处理过,但我找不到解决此问题的方法。 我在这样的类中声明了一个static const std::string[]成员:

.h:

class MyClass
{
private:
    static const std::string cArray[aNumber];

    //other stuff like ctors & all
}

.cpp

const std::string MyClass::cArray[] = {"", "ini", "txt", "bmp"};

这个类包含在另一个标题中,我声明了MyClass的static const array[]。 问题是:当构建这些数组时,m_cArray包含空字符串,我用它来修复其他静态数组中的东西。

我在静态初始化顺序问题上看到了一些线程,但我没有找到有用的答案。

欢迎提出建议。感谢

3 个答案:

答案 0 :(得分:3)

您在静态成员定义期间忘记指定cArray属于类MyClass

const std::string MyClass::cArray[] = {"", "ini", "txt", "bmp"};
//                ^^^^^^^^^^^^^^^

编辑:

您的问题似乎是在C ++中未定义静态成员的初始化顺序。

正如here所说,最优雅的方法是将初始化包装在一个函数中:

class MyClass
{
private:
    static std::string* Array()
    {
        static std::string cArray[aNumber] = {"", "ini", "txt", "bmp"};
        return cArray;
    }
};

您可以通过以下方式访问阵列:

MyClass::Array();

编辑:您在示例中更正了此错误

也许您的另一个错误可能是您在班级声明中命名了您的成员cArray

class MyClass
{
private:
    static const std::string cArray[aNumber];
    //                       ^^^^^^
};
成员定义中的

m_cArray

const std::string m_cArray[] = {"", "ini", "txt", "bmp"};
//                ^^^^^^^^

我在第一个代码示例中更正了此错误。

答案 1 :(得分:2)

您需要说明哪个类cArray是初始化时的成员

const std::string MyClass::cArray[] = {"", "ini", "txt", "bmp"};

答案 2 :(得分:1)

你的问题似乎确实源于臭名昭着的静态初始化顺序惨败

基本上,当您在一个翻译单元中有static变量X时,在第二个翻译单元中引用另一个static变量Y,那么您的程序就有50个/ 50次行为不端的可能性。为了正常行事,Y应该在X之前初始化,但C ++不强制执行。{/ p>

据我所知,处理此问题的唯一正确方法是使用函数级static变量,以确保在m_array的第一次调用时初始化MyClass::array()(在C ++ 11中,这种初始化甚至可以保证是线程安全的:

struct MyClass {
    static const size_t arraySize = 4;

    // This function could be defined in a .cpp rather than inline
    // I only put it inside the class for compactness/readability reasons
    static const std::string* array() {
        static const std::string m_array[arraySize] = {"", "ini", "txt", "bmp"};
        return m_array;
    }
};

// In some other file
struct OtherClass {
    // This function could be defined in a .cpp rather than inline
    static void whatever() {
        do_something_with(MyClass::array());
    }
};

换句话说,你应该避免声明static全局变量或类变量(除非你绝对确定它们可以被解析为编译时常量,如上面的arraySize ),但将它们包含在static函数内的函数级别。


作为旁注,这个习惯用法使你更容易使用合适的容器而不是传统的C数组,例如。 std::vector或者,如果您使用的是C ++ 11,则std::array

// C++03
struct MyClass {
    // This function could be defined in a .cpp rather than inline
    static const std::vector<std::string>& data() {
        static std::vector<std::string> m_data;
        if (m_data.empty()) {
            m_data.push_back("");
            m_data.push_back("ini");
            m_data.push_back("txt");
            m_data.push_back("bmp");
        }
        return m_data;
    }
};

// C++11
struct MyClass {
    using Container = std::vector<std::string>;
    // or
    // using Container = std::array<std::string, 4>;

    // This function could be defined in a .cpp rather than inline
    static const Container& data() {
        static const Container m_data = {"", "ini", "txt", "bmp"};
        return m_data;
    }
};