开发者

Initializiation confusion

Not sure of the appropriate title, but it stems from this discussion:

Do the parentheses after the type name make a difference with new?

On Visual Studio 2008, when I run the following code:

struct Stan
{
    float man;
};

int main()
{
    Stan *s1 = new Stan;
    Stan *s2 = new Stan();

}

Examining the locals, s1 has an uninitialized float with a random value. s2 is value initialized to 0.

Howeve开发者_如何学JAVAr, if I add a string data member, the float in both instances is uninitialized.

struct Stan
    {
            std::string str;
        float man;
    }; 

However, the string in both instances is initialized. I tried adding other non-POD classes instead of a string, but the latter case only occurs if I add a string data member. I gather that adding a string still keeps it a POD class? If it wasn't a POD class, then it should have value initialized regardless of the parenthesis, right? Any ideas why floats(and other primitive data types for that matter) aren't initialized when I add a string data member?


Adding a string stops the struct from being a POD class because a POD class must be an aggregate class with no members of type non-POD-struct and std::string has (amongst other things) user-declared constructors which makes it a non-POD-struct.

This is a known bug/feature of Visual Studio 2008. It doesn't support C++03 value initialization for non-POD types such as the structure in your second example.

With the struct as in your second example what should happen is the float is not initialized by new Stan but is zero initialized in new Stan().

Types with a user declared default constructor are initialized by calling that constructor in all cases, this happens correctly.

See here and here.


The behavior that you observe is a conforming behavior from the point of view of C++98 specification of the language.

The type in your first example is a so-called POD (Plain Old Data) type. When you apply the () initializer to a POD class type it performs zero-initialization of all data members of the class.

The type in your second example is not a POD type (because of the non-POD member str). When you apply the () initializer to a non-POD class type, it simply calls the class constructor to perform initialization. In your case the implicit [compiler-provided] constructor will properly initialize the str member, but will not do anything for the man member, which is why you see garbage in it.

Again, this is the correct behavior in C++98. It was changed in C++03. In C++03 the () initializer will perform value-initialization. In accordance with the rules of value-initialization, in your second example, the man field should also get zero-initialized in response to () initializer.

See also https://stackoverflow.com/questions/1976185/what-is-the-difference-between-new-myclass-vs-new-myclass for more detailed explanation .

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜