静态常量字符串不会被初始化

发布于 2024-08-05 09:14:56 字数 522 浏览 2 评论 0原文

我有一些静态常量字符串作为我的 C++ 类的私有成员。我知道 .h 中的声明和 .cpp 实践中的定义(和初始化)。在类构造函数中,我调用一个使用这些静态字符串的函数。令人惊讶的是,在构造函数中,字符串保持未初始化(空字符串),这会产生问题。

有人可以指出这里可能出了什么问题吗?我一直使用静态常量字符串,但从未遇到过这种情况。

更新:m_data 在 utility() 中保持为空。我有一个 Test 类对象作为另一个类的私有成员。

这是我正在使用的一种代码:

// Test.h
class Test
{
public:
  Test();
private:
  void utility();

 static const std::string m_data;
};

// Test.cpp
const std::string Test::m_data = "Data";

Test::Test()
{
utility();
}

void Test::utility()
{
//use m_data here
}

I have some static const strings as private members of my C++ class. I am aware of the declaration in .h and definition (and initialization) in .cpp practice. In the class constructor I invoke a function that uses these static strings. Surprisingly when in constructor, the strings remain uninitialized (empty strings) which is creating a problem.

Can somebody point out what might be going wrong here? I work with such usage of static const strings all the time but never ran into such situations.

Update: m_data remains empty in utility(). I have a Test class object as a private member of another class.

Here is a kind of code I am using:

// Test.h
class Test
{
public:
  Test();
private:
  void utility();

 static const std::string m_data;
};

// Test.cpp
const std::string Test::m_data = "Data";

Test::Test()
{
utility();
}

void Test::utility()
{
//use m_data here
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

故事未完 2024-08-12 09:14:56

你的 TEST 类型的对象是全局的吗?

如果是这样,那么您就会遇到初始化顺序的问题。

IE。

int main()
{
    std::cout << "Main Entered" << std::endl;
    Test  t; // This should work
}
Test  plop; // This may not work depending

解决方案是使用静态方法来获取字符串:

class Test
{
    static std::string const& getData()
    {
        static std::string const data("PLOP");
        return data;
    }
    // STUFF
    // Remove this line
    // static const std::string m_data;
    Test::Test()
    {
        std::cout << "Test::Test()" << std::endl;
        Utility();
    }
};
// If "Test::Test()" is printed before "Main Entered"
// You have a potential problem with your code.

Is your object of type TEST a global?

If so you are then running into the problem with initialization order.

ie.

int main()
{
    std::cout << "Main Entered" << std::endl;
    Test  t; // This should work
}
Test  plop; // This may not work depending

The solution is to use a static method to get the string:

class Test
{
    static std::string const& getData()
    {
        static std::string const data("PLOP");
        return data;
    }
    // STUFF
    // Remove this line
    // static const std::string m_data;
    Test::Test()
    {
        std::cout << "Test::Test()" << std::endl;
        Utility();
    }
};
// If "Test::Test()" is printed before "Main Entered"
// You have a potential problem with your code.
烟─花易冷 2024-08-12 09:14:56

您是这么定义的吗?

class X
{
public:
      static string i;
};
string X::i = "blah"; // definition outside class declaration

请参阅:静态数据成员(仅限 C++)

Are you defining it as such?

class X
{
public:
      static string i;
};
string X::i = "blah"; // definition outside class declaration

See: Static data members (C++ only)

忘东忘西忘不掉你 2024-08-12 09:14:56

根据当前代码,我猜您尝试创建全局测试实例,很可能在不同的 .cpp 文件中。看来您遇到了可怕的 静态初始化顺序惨败。简单地说:.cpp 文件中的全局/静态成员变量将按照它们定义的顺序进行初始化。不保证不同 .cpp 文件中的全局变量,您不能依赖一个文件中的 var 在另一个文件中的全局变量之前或之后初始化。

Based on current code I'd guess you try to create global Test instance, most probably in a different .cpp file. Seems like you are hitting the dreadful static initialization order fiasco. Simply put: the global/static-member variables in a .cpp file will be initialized in the order they are defined. No guarantees are made about global variables in different .cpp files, you cannot rely on var in one file being initialized before or after global variable in another.

絕版丫頭 2024-08-12 09:14:56

这是你需要的吗?

class blah{
    static const string sz;
public:
    blah(){
        cout<<"blah constructor - string initialized to: "<<sz.c_str()<<endl;
    }
};

const string blah::sz("Hello, Blah!");

int _tmain(int argc, _TCHAR* argv[]){
    blah b;
    return 0;
}

程序输出blah构造函数 - 字符串初始化为:Hello, Blah!

Is this what you need?

class blah{
    static const string sz;
public:
    blah(){
        cout<<"blah constructor - string initialized to: "<<sz.c_str()<<endl;
    }
};

const string blah::sz("Hello, Blah!");

int _tmain(int argc, _TCHAR* argv[]){
    blah b;
    return 0;
}

Program Output: blah constructor - string initialized to: Hello, Blah!

巷雨优美回忆 2024-08-12 09:14:56

我检查了该程序,它运行良好。您使用什么 IDE 进行工作?
这在 Windows 上对吗?

如果我错误地定义了您声明成员的类本身,则可以使用它,原因是它是 const static。

I mase a check of the program anbd it worked fine. In what IDE are you working with ?
This on windows right ?

You can use if I am mistaken make the definition if the class itself where you declare the member, the reason cause it is a const static.

情域 2024-08-12 09:14:56

我会使用不同的方法:

class Test
{
public:
    Test() : m_data( "Data" ) {}
private:
     const std::string m_data;
};

我个人更喜欢这种“风格”,它将消除在构造函数中初始化数据的任何问题,而为每个实例构造字符串的成本可能很小。

I'd use a different approach:

class Test
{
public:
    Test() : m_data( "Data" ) {}
private:
     const std::string m_data;
};

I personally prefer this 'style' and it would remove any issues with having initialised data in the constructor at what is likely to be the minor cost of constructing the string for each instance.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文