1

I am reading "Accelerated C++" by Andrew Koenig and Barbara E. Moo, and I'm at the chapter about constructors (5.1).

They mention here that

We said that constructors exist to ensure that objects are created with their data members in a sensible state. In general, this design goal means that every constructor should initialize every data member. The need to give members a value is especially critical for members of built-in type. ...

Although we explicityly initialized only midterm and final, the other data members are initialized implicitly. Specifically, n is initialized by the string default constructor, and homework is initialized by the vector default constructor.

The class they are talking about is

class Student_info {
public:
    std::string name() const (return n;}
    bool valid() const {return !homework.empty();}
    std::istream& read(std::istream&);

    double grade() const;
private:
    std::string n;
    double midterm, final;
    std::vector<double> homework;
};

and their default constructor is

Student_info::Student_info(): midterm(0), final(0) {}

I would just like to clarify that this means that things like int and double where there isn't a std:: before the term will need to be initialized specifically?

Community
  • 1
  • 1
sccs
  • 1,123
  • 3
  • 14
  • 27
  • "need to be initialized _specifically_" - You can actually leave out the _specific_ value, and they'll still be initialized All such basic types have a zero value. `: midterm()` would set the member to `0.0` because that's the zero value for `double`. Similarly, if you put an `int` member in the initializer list, but provide no inital value, it would be initialized to `0`. – MSalters Mar 22 '13 at 23:15

5 Answers5

3

That is correct.
But std:: is not what you are looking for.

Any of the fundamental types are not initialized unless you do it explicitly.

So char/int/float/pointers etc. Also (as noted by Ian below) any class/unions without an explicit constructor will default initialize its members (which means fundamental (and recursively for member s of class/unions without and explicit constructor) that they are left undefined).

A side note:

  • This rules applies to automatic and dynamic storage duration objects
  • Static and thread storage duration objects are zero initialized.
Martin York
  • 257,169
  • 86
  • 333
  • 562
2

int and double are built-in types, not classes, so they don't have default constructors, and are undefined by default. For example:

int a;
Student_info s;

The syntax for both variables is the same, but the value of a is undefined, while the value of s is defined because Student_info s actually calls the constructor, i.e. Student_info s = Student_info();.

ebsddd
  • 1,028
  • 9
  • 20
1

The author is just trying to show a default constructor where everything is defaulted to the equivalent of 0. For string and vector, those will just be empty. For primitive types such as int and double, the initial value of these primitives during declaration is defaulted to the value that was in memory that variable points to. This does depend on the compiler though

Hien
  • 165
  • 2
  • 11
  • 2
    The value is not defaulted. It is undefined. And reading a variable that is not initialized is undefined behavior. – Martin York Mar 22 '13 at 06:51
  • well, I guess my professor lied to me then. Regardless, this depends on the compiler. It may be undefined for ancient C and C++ compilers, but the one I have used so far default the values to 0 – Hien Mar 22 '13 at 07:07
  • 2
    No. You miss understood what your professor said (the value is random and depends on what is memory and thus random). But the variable is in undefined state. The standard says using a variable in an undefined state is bad. You are seeing 0 because you are compiling in debug mode (which usually does initialize memory because that makes debugging easier). In release mode it will not initialize memory unless you explicitly do it for the extra performance. – Martin York Mar 22 '13 at 07:13
1

It is not related to std namespace. n and homework are classes, their constructor will be called during the construction of Student_info. But midterm and final are primitive values, there aren't constructors for them. Initialize the primitive member in constructor is not necessary but a good manner.

Shawnone
  • 850
  • 5
  • 17
0

There is more to it.

1) For primitive or built-in types, implicitly initialized (or compiler initialized) means no-op (does nothing).

2) For primitive or built-in types, explicitly initialized (or initialized by the programmer) is obvious :)

As in your example:

    Student_info::Student_info(): midterm(0), final(0) {}

3) For non-primitive types, implicitly initialized (or compiler initialized) means compiler may (or may not) synthesis a constructor for the purpose of initialization.

 Usually, a constructor is synthesized by the compiler under the following cases:

 a) The non-primitive type is polymorphic or derives from some polymorphic/non-polymorphic types,
 b) The non-primitive type has a polymorphic/non-polymorphic member. 

 Compiler synthesized constructor will usually have code to 

 a) initialize v-pointer to v-table, 
 b) call base class constructor, 
 c) call constructors of members, so on, 

 basically driven by the definition of non-primitive type.

4) For non-primitive types, explicitly initialized (or initialized by the user supplied constructor) means compiler would make a call to the user defined constructor instead of synthesizing one for the purpose of initialization.

For example, the default constructor defined by the respective non-primitive types (like std::string or std::vector) gets invoked.

**

Note: Compiler may still augment code inside the user-defined constructor to do some behind-the-scenes initialization as need be (look at step-3 above for such needs). Such augmented code will always be inserted before the user-defined code inside the constructor!

**

Arun
  • 2,087
  • 2
  • 20
  • 33
  • Almost (very) good, but you are messing default construction ("compiler initialized") and the compiler generation of the def constr. Explicit initialization - you explicitaly call the constructor (no matter what exactly, can be the def constr, even one generated by compiler) and implicit or def const, the compiler call the def constr for you, no matter it is autom generated by compiler or user defined. Default constructor is simple the one without arg. – qPCR4vir Mar 22 '13 at 08:16
  • Here is an extreme example of what Im trying to explain: http://stackoverflow.com/a/15416693/1458030 – qPCR4vir Mar 22 '13 at 09:18
  • Sorry your comment is bit confusing. ""you are messing default construction ("compiler initialized")"" => Default construction is not always compiler initialized. That becomes evident when we supply a default constructor (the one without any parameter). The compiler is bound to call user defined default constructor whenever default construction happens. – Arun Mar 22 '13 at 11:06
  • I agree with your "Explicit" vs "Implicit" initialization, but didn't quite understand how my post is contradicting it! I just gave an explanation of how initialization happens behind the scenes by using either compiler generated or user defined constructors. Also, most books do not discretely point out the reasons behind synthesis of a default constructor. I just tried to explain it here. – Arun Mar 22 '13 at 11:23
  • Here is some more detailed description: http://stackoverflow.com/questions/9635772/is-it-true-that-a-default-constructor-is-synthesized-for-every-class-that-does-n – Arun Mar 22 '13 at 11:58
  • Well, maybe it was your last example what "mess" me. In the original OP code n and homework are implicitaly (your punkt 3) initialized using a non-compiler-generated def constr, but you mention string and vector in yours punkt 4...Hmm here you write "explicitly initialized (or initialized by the programmer) means compiler would make a call to the user defined constructor" -no, you can explicitaly init using a non user-defined constr (default or copy/move) – qPCR4vir Mar 22 '13 at 13:33
  • Good catch! in punkt 4, " (or initialized by the programmer)" is the culprit. It is somewhat misleading. Redited. Thank u :) – Arun Mar 22 '13 at 14:01