简体   繁体   中英

Why are objects default initialized but primitives aren't in C++?

Why are primitives not default initialized but objects are in C++? For example:

class Foo {
  void Method() {
    int w(); // initialized to 0
    int x; // uninitialized
    std::vector<int> y(); // initialized to empty vector
    std::vector<int> z; // initialized to empty vector
  }
}

In this case, w and y are declared with parentheses, and so are initialized, and z is declared without, and gets its no argument default constructor called, but x remains uninitialized. Why is this?

If there is no initializer for an object, the object is default initialized [dcl.init]/12 . If the initializer is () , the object is value initialized [dcl.init]/11 . Default initialization of an object of class type (like std::vector<int> ) invokes the default constructor while default initialization for an object of type int means no initialization [dcl.init]/7 . Value initialization will also call the default constructor for objects of class type that have one (like std::vector<int> does), but for objects of type int , value initializtion means zero initialization [dcl.init]/8 . And zero initialization for an int does actually mean that the int is initialized to zero [dcl.init]/6

As has already been pointed out in the comments,

int w();

and

std::vector<int> y();

are not in fact definitions of a local variable, but rather declarations of two functions w and y that take no arguments and return an int and an std::vector<int> respectively (the infamous most vexing parse ). Nevertheless, there are cases where it is possible to use () as an actual initializer, so let's modify your example a bit to demonstrate the behavior you were asking about:

class Foo
{
    int w;
    std::vector<int> y;

    Foo()
      : w(),  // value initialized == zero initialized for int
        y()   // value initialized == default initialized for std::vector<int>
    {
        int x; // default initialized == uninitialized for int
        std::vector<int> z; // default initialized
    }
};

The "why" here simplifies to "Because C++ was trying to keep performance and behaviors C compatible where it could". When you're selling a new, relatively low-level language that (at least initially) was mostly a superset of C, you don't want to say "If you compile existing C code as C++, it's always slower!" C doesn't zero-initialize primitives by default; as long as the code eventually assigns a value to them before reading from them, that's fine, and C++ follows the same pattern.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM