Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
357 views
in Technique[技术] by (71.8m points)

initialization - C++ Default constructor

Given the following code:

class temp
{
public:
    string str;
    int num;
};

int main()
{
    temp temp1;
    temp temp2 = temp();

    cout << temp1.str << endl; //Print ""
    cout << temp2.str << endl; //Print ""

    cout << temp1.num << endl; //Print a rand num
    cout << temp2.num << endl; //Print 0
}

What is the different between these two?—

temp temp1;

and

temp temp2 = temp();
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
temp temp1;

This calls temp's default constructor on the instance called temp1.

temp temp2 = temp();

This calls temp's default constructor on a temporary object, then calls the compiler-generated copy-constructor on temp2 with the temporary object as the argument (this of course assumes that the compiler doesn't elide copies; it depends on your compiler's optimization settings).

As for why you get different initialized values, section 8.5 of the standard is relevant:


8.5 Initializers [dcl.init]

Paragraph 5:

To zero-initialize an object of type T means:
  • if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T;
  • if T is a non-union class type, each nonstatic data member and each base-class subobject is zero-initialized;
  • if T is a union type, the object’s first named data member is zero-initialized;
  • if T is an array type, each element is zero-initialized;
  • if T is a reference type, no initialization is performed.

To default-initialize an object of type T means:

  • if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
  • if T is an array type, each element is default-initialized;
  • otherwise, the object is zero-initialized.

To value-initialize an object of type T means:

  • if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
  • if T is a non-union class type without a user-declared constructor, then every non-static data member and base-class component of T is value-initialized;
  • if T is an array type, then each element is value-initialized;
  • otherwise, the object is zero-initialized.

Paragraph 7:

An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.

Paragraph 9:

If no initializer is specified for an object, and the object is of (possibly cv-qualified) non-POD class type (or array thereof), the object shall be default-initialized; if the object is of const-qualified type, the underlying class type shall have a user-declared default constructor. Otherwise, if no initializer is specified for a nonstatic object, the object and its subobjects, if any, have an indeterminate initial value; if the object or any of its subobjects are of const-qualified type, the program is ill-formed.

12 Special Member Functions [special]

Paragraph 7:

An implicitly-declared default constructor for a class is implicitly defined when it is used to create an object of its class type (1.8). The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with an empty mem-initializer-list (12.6.2) and an empty function body.

12.6.2 Initializing bases and members [class.base.init]

Paragraph 4:

If a given nonstatic data member or base class is not named by a mem-initializer-id (including the case where there is no mem-initializer-list because the constructor has no ctor-initializer), then
  • If the entity is a nonstatic data member of (possibly cv-qualified) class type (or array thereof) or a base class, and the entity class is a non-POD class, the entity is default-initialized (8.5). If the entity is a nonstatic data member of a const-qualified type, the entity class shall have a user-declared default constructor.
  • Otherwise, the entity is not initialized. If the entity is of const-qualified type or reference type, or of a (possibly cv-qualified) POD class type (or array thereof) containing (directly or indirectly) a member of a const-qualified type, the program is ill-formed.

So now that the rules have been laid out, let's see how they apply:

temp temp1;

temp is a non-POD type (because it has a std::string member), and since no initializer is specified for temp1, it will be default-initialized (8.5/9). This calls the default constructor (8.5/5). temp has an implicit default constructor (12/7) which default-initializes the std::string member and the int member isn't initialized at all (12.6.2/4).

temp temp2 = temp();

On the other hand, the temporary temp object is value-initialized (8.5/7), which value-initializes all data members (8.5/5), which calls the default constructor in the std::string member and zero-initializes the int member (8.5/5).

Of course, if you much rather not have to refer to the standard in 5+ different places, just ensure that you explicitly initialize everything (e.g. int i = 0; or using initializer lists).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...