c++ - Initialize standard stream objects

前端 未结 2 812
死守一世寂寞
死守一世寂寞 2021-01-25 19:06

In what cases and why is this necessary:

class ios_base::Init {
    static int init_cnt;  // internal static counter (for exposition only)
public:
    Init();
           


        
2条回答
  •  不要未来只要你来
    2021-01-25 19:17

    They're needed to ensure the correct initialization of the standard iostream objects, like std::cout. Basically, the standard iostream objects are guaranteed to be constructed by the time the first constructor of ios_base::Init has finished. (The init_cnt member is part of one technique of achieving this.) In addition, the standard says that including declares a static instance of ios_base::Init (or behaves as if it does), so if you write:

    #include 
    
    class X
    {
    public:
        X() { std::cout << "something";
    };
    X anXwithStaticLifetime;
    

    you're guaranteed that std::cout will be constructed before the constructor of anXwithStaticLifetime is run.

    Of course, this only works within a single translation unit. If you define in a header ("X.hh"):

    class X
    {
    public:
        X();
    };
    

    and then in two different translation units:

    #include "X.hh"
    #include 
    
    X::X()
    {
        std::cout << "something";
    }
    

    and:

    #include "X.hh"
    X anXwithStaticLifetime;
    

    it's quite possible that std::cout will not have been constructed when you execute the constructor. The usual way of ensuring this is to define a local instance of ios_base::Init in the constructor:

    X::X()
    {
        static ios_base::Init toEnsureInitialization;
        std::cout << "something";
    }
    

    In practice, most implementations use additional tricks to reduce the risk. But as far as I know, none of them are 100%, and depending on how you link, you can still get into problems. But they won't occur if you do things the usual way. With the results that a lot of programmers aren't aware of the risk, and don't make the necessary declaration (and it almost always works anyway).

提交回复
热议问题