1

I have searched previous questions, and have not found a satisfying answer to my question:

If I define an empty default constructor for a class, as for example

class my_class{
public:
    myclass(){}
private:
    int a;
    int* b;
    std::vector<int> c;
}

my understanding is that if I define an object using the default constructor, say

my_class my_object;

then my_object.a will be a random value, the pointer my_object.b will also be a random value, however the vector c will be a well-behaved, empty vector.

In other words, the default constructor of c is called while the default constructors of a and b is not. Am I understanding this correctly? What is the reason for this?

Thank you!

2
  • 2
    Plain old datatypes (PODs) do not have constructors. Commented Jul 8, 2015 at 21:07
  • 1
    I'm being a bit pedantic here because I have seen people attempt to use uninitialized values as a random number generator. Better terms for the state and contents of a and b are uninitialized and undefined, respectively. Random doesn't work, but cause the contents are not random. They may be unbelievably predictable, for example a canary value like DEADBEEF. A nice C++ implementation may set them to 0 for you. The point is you can't count on any behaviour. Commented Jul 8, 2015 at 21:14

2 Answers 2

7

a and b have non-class types, meaning that they have no constructors at all. Otherwise, your description is correct: my_object.a and my_object.b will have indeterminate values, while my_object.c will be properly constructed.

As for why... by writing a user-defined constructor and not mentioning a and b in the initializer list (and not using C++11 in-class member initializers) you explicitly asked the compiler to leave these members uninitialized.

Note that if your class did not have a user-defined constructor, you'd be able to control the initial values of my_object.a and my_object.b from outside, by specifying initializers at the point of object declaration

my_class my_object1;
// Garbage in `my_object1.a` and `my_object1.b`

my_class my_object2{};
// Zero in `my_object2.a` and null pointer in `my_object2.b`

But when you wrote your own default constructor, you effectively told the compiler that you want to "override" this initialization behavior and do everything yourself.

Sign up to request clarification or add additional context in comments.

10 Comments

It's also good to note the difference between object o = object() and object o; for POD types (no constructor), the former will default-initialize all members, even the ones without constructors (setting their bits to 0). Similarly, in your constructor's initializer list you could write : a(), b() which would also default-initialize a and b to 0.
@user3208430: int variables and pointer variables do not have implicit default constructors. It is true that int i = int(); or int i{}; initializes i to zero, but this initialization process does not involve any constructors.
@user3208430: It will depend on the constructor of the enveloping class in pretty much the same way. If the enveloping class has a user-defined constructor that doesn't bother to initialize that inner my_class member, a and b will end up with garbage.
It might be worth noting in the answer that this distinction between a and b on the one hand and c on the other hand is called "trivial" in the spec; a and b are trivial, and c is not. Or to zoom in further, a and b are trivially constructible, c is not. "trivial" is different from both POD and primitive, which many people incorrectly cite as the criteria to get this differing behavior.
@Cameron "only if you call it with ()/{} will the members be default initialized." - they're value-initialized. They're default-initialized in the case of no () or {}, and said-initialization for those is to do... nothing.
|
2

Since a and b are not objects but primitive datatypes, there is no constructor to call. In contrast, c is an object, so its default constructor is called.

13 Comments

a and b will be objects once a myclass is instantiated.
@juanchopanza No they aren't. Not every variable is an object in C++. Anything of a primitive type (int, char, long, short, any pointer, bool, etc) is not an object.
@GabeSechan Yes, they are. You are quite mistaken.
@juanchopanza No they aren't. THey're primitives. The term object is reserved for classes, structs, and unions. Please study up on C++.
@Cameron In 1.8 The C++ object model [intro.object]. "An object is a region of storage". There is no distinction between built-ins and user-defined types.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.