1

www.fredosaurus.com states this:

When an object of a class is created, C++ calls the constructor for that class. If no constructor is defined, C++ invokes a default constructor, which allocates memory for the object, but doesn't initialize it.

But I thought constructors are only responsible for initializing data members. Is my understanding incorrect?

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • 9
    It's wrong. The storage for the object itself isn't allocated by the c'tor. Discard that poor tutorial and [pick a good book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) – StoryTeller - Unslander Monica Sep 24 '17 at 06:04
  • Don't rely on arbitrary Internet garbage. Use a reliable source. At least a book that has been technically reviewed. – user207421 Sep 24 '17 at 06:44

1 Answers1

5

To reiterate my comment, that tutorial is wrong. The storage for the object itself is not the responsibility of the constructor. If you look at the C++ standard definition of object lifetime [basic.life]/1:

The lifetime of an object or reference is a runtime property of the object or reference. An object is said to have non-vacuous initialization if it is of a class or aggregate type and it or one of its subobjects is initialized by a constructor other than a trivial default constructor. [ Note: Initialization by a trivial copy/move constructor is non-vacuous initialization.  — end note ] The lifetime of an object of type T begins when:

  • storage with the proper alignment and size for type T is obtained, and

  • if the object has non-vacuous initialization, its initialization is complete,

You'll see that obtaining the storage is a separate item in the description of the objects lifetime. And for a good reason, since storage can be obtained in a multitude of ways:

  1. It may be static storage. So the c'tor can only initialize the object.
  2. It may be automatic storage, where again it's the run-time that manages it, not the c'tor, every time a scope is entered.
  3. It could be storage obtained by dynamic allocation, with the use of operator new. Again, not something the c'tor will do.

The constructor is always operating on storage (however obtained) to make an object come into existence there.

The quote you got from the site is wrong two-fold. Since a default c'tor could very well initialize the object to have valid state. Consider this:

struct foo {
  std::string a;
  std::string b;
};

There is no user defined c'tor, so a compiler generated one will be synthesized. And you can be certain that it will default initialize the two strings into a valid state (as empty strings).

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • One more question @StoryTeller If a constructor doesnt initializes the fundamental type members(explicitly) inside the class are they (members) initialized implicitly? –  Sep 24 '17 at 06:23
  • 3
    @RoshanRimal - A constructor always initializes all the members. The problem is that some members (like fundamental types) have their default initialization specified as giving indeterminate values. This is different than initializing them in the member initialize list however. When you have a member `int c;` and you write `foo() : c{} {}` then it will *zero initialize* `c`. – StoryTeller - Unslander Monica Sep 24 '17 at 06:26
  • will int member be initialized to 0 if i have a default and empty constructor? –  Sep 24 '17 at 06:40
  • @RoshanRimal - If you mean you have `foo() : {}` then `c` will be *default initialized* (remember the c'tor initializes all the members, always). Default initialization for `c` is defined as giving it an indeterminate value ("garbage" as some like to call it). – StoryTeller - Unslander Monica Sep 24 '17 at 06:42
  • @RoshanRimal Take a look at https://stackoverflow.com/questions/620137/do-the-parentheses-after-the-type-name-make-a-difference-with-new. The rules are the same. BTW if this is giving you a headache, its because that's what this fiasco does to people – Passer By Sep 24 '17 at 06:43
  • Default initialization for an int is 0, not garbage. You can see this by defining a global int c; so the cobstructor does not initialize c. – lalala Sep 24 '17 at 07:00
  • @lalala - Objects with static storage duration are **defined** to be zero initialized before any other initialization occurs. Your assertion proves nothing. – StoryTeller - Unslander Monica Sep 24 '17 at 07:02
  • @StoryTeller a default constructor is said to establish a valid state of an object but in this example: class foo{ int i ; foo(){} }; foo bar; bar.i is assigned garbage value or indeterminate value so is it said to be in a valid state.Also is the default constructor of a class responsible for default initialization?Sorry for the unformatted code because of character limitation and thanks in advance –  Sep 25 '17 at 04:05
  • @RoshanRimal - A default c'tor default initializes an object. It isn't said to do anything else. In you example, you omitted initialization for `i` so it's default initialized. So when we default initialize `foo`, it will have an indeterminate value. But in my previous comment, the default c'tor of `foo` explicitly value initializes `c` to 0. So when we default initialize `foo`, `c` gets a meaningful state. – StoryTeller - Unslander Monica Sep 25 '17 at 05:27
  • @StoryTeller sorry for the trouble but some more thing i want to be clear about is default initialization, Is default initialization a initialization through default c'tor of a class?(if not please explain that) and how would you define default initialization for basic types(like int float) which are non classes. Also one more thing if i dont specify in the c'tor to initialize member varaiable i ,it will be default initialized(as you said) so my question is who is responsible for default initializing that i. –  Sep 25 '17 at 08:46
  • @RoshanRimal - I think you'd have it easier if you read about it [here](http://en.cppreference.com/w/cpp/language/initialization). It becomes clearer once you have it all. As for your question (1) Yes. And even fundamental types have c'tors officially. They are just no-ops. (2) Invocation of that no-op c'tor. (3) The compiler. It's obligated to initialize all members. If you don't specify how, it uses default initialization. And if there is no default c'tor, it emits an error for you to know. – StoryTeller - Unslander Monica Sep 25 '17 at 09:04
  • @RoshanRimal - Glad to hear. Now, could you mark the answer as accepted if you got it? It's the checkbox there. Gives a nice rep-bonus to both of us. – StoryTeller - Unslander Monica Sep 25 '17 at 09:16
  • @StoryTeller sure! –  Sep 25 '17 at 09:17