How Do C++ Class Members Get Initialized If I Don't Do It Explicitly

How do C++ class members get initialized if I don't do it explicitly?

In lieu of explicit initialization, initialization of members in classes works identically to initialization of local variables in functions.

For objects, their default constructor is called. For example, for std::string, the default constructor sets it to an empty string. If the object's class does not have a default constructor, it will be a compile error if you do not explicitly initialize it.

For primitive types (pointers, ints, etc), they are not initialized -- they contain whatever arbitrary junk happened to be at that memory location previously.

For references (e.g. std::string&), it is illegal not to initialize them, and your compiler will complain and refuse to compile such code. References must always be initialized.

So, in your specific case, if they are not explicitly initialized:

    int *ptr;  // Contains junk
string name; // Empty string
string *pname; // Contains junk
string &rname; // Compile error
const string &crname; // Compile error
int age; // Contains junk

Is it mandatory to initialize class members if a constructor is explicitly defined?

When a constructor is declared for a class, initialization of the class objects becomes mandatory.

It's true, but initialization doesn't have to be explicit. Note the term objects instead of member.

Class-type members will be default-intialized if you don't explicitly do it.

class A {};
class B
{
A a;
int x;
B()
{
//a is initialized here, although you didn't do it explicitly

//x is not initialized, nor is it mandatory to initialize it
//but x is not an object
}
};

Of course, "mandatory" is a strong word. It's not mandatory to initialize x, but you can't do anything with it until you do. :)

Is there a way to late-initialize a member variable (a class) in C++?

MY suggestion: Use a function:

private: static int calculate_first(int input) {return input*5;}
explicit Second(int input) : first(calculate_first(input)) {}

Base classes will be initialized in the order they're declared in the class inheritance list, and then members will be initialized in the order that they're listed in the class, so the calculation can depend on non-static member-variables and base classes if they have already been initialized.


Alternatively:

Default constructor, then reassign:

explicit Second(int input) { first = input*5; }

Dummy value, then reassign:

explicit Second(int input) : first(0) { first = input*5; }

Use boost::optional (or std::optional as of C++17):

boost::optional<First> first;
explicit Second(int input) { first = input*5; }

Use the heap:

std::unique_ptr<First> first;
explicit Second(int input) { first.reset(new First(input*5));}
Second(const Second& r) first(new First(*(r->first))) {}
Second& operator=(const Second& r) {first.reset(new First(*(r->first)));}

Placement new:

This is tricky and not suggested 
and worse in every way than boost::optional
So sample deliberately missing.
But it is an option.

Explicitly initialize member which does not have a default constructor

You are almost there. When you create an object in C++, by default it runs the default constructor on all of its objects. You can tell the language which constructor to use by this:

MyClass::MyClass() : myObject(60){

myObject.doSomething();

}

That way it doesn't try to find the default constructor and calls which one you want.

Do constructors have to initialize member variables in C++?

It really depends on what member variables you have. If you provide a constructor and don't explicitly initialize a variable in the member initialization list, then it will be default initialized. And this is for every variable.

Now, default initialization does something else depending on what variable you have. If you have a builtin type, like int or bool, then it will not be initialized to 0 or any other value, just like if you had:

int value; // it has an indeterminate value

This also applies to arrays. If it is another class, then the default constructor of that class will be called, just like if you had:

struct Foo { /*something*/ };
Foo value; // calls default constructor, i.e. initializes object

Should constructor initialize all the data members of the class?

Should constructor initialize all the data members of the class?

That would be a good practice.

So, does C++ encourage us to initialize all the data members in the constructor?

It's not required by the c++ standard. As long as you initialize all variables before they're used, your program is correct in that regard.

or it is just Eclipse's logic?

Quite likely. Neither g++ nor clang versions that I tested warn about this when all warnings are enabled. The logic may or might not be based on high integrity c++ coding standard
12.4.2 or some other coding standard or style guide.

Why aren't union member data default-initialized?

So as you can see: the union U didn't initialize its member data a_ and i_

A union only ever has one member active, so there is never a case where two members could be initialised.

No member of a union initialised if you don't provide an initialiser in a user defined constructor.

const member isn't explicitly initialized but compiles

If a class has const-qualified member variables, then for any constructor defined for that class, those variables must be initialized in the constructor initializer list. If any defined constructor does not initialize a const-qualified member variable, the program is ill-formed.

In your example code, someClass has no user-declared constructors, so there is an implicitly declared default constructor. However, if that constructor is not used, then it is not defined. Since you do not instantiate any someClass object, the constructor is not used. Hence, your example code does not have any errors.

If you were to define a constructor for the class and not initialize the const member,

class someClass
{
someClass() { } // error, does not initialize const-qualified x
int const x;
};

or if you were to instantiate an instance of someClass (which would cause the implicitly declared default constructor to be defined), then the program would be ill-formed.

Best way to initialize class members?

The second example is not initialisation.

So, of the two examples, the first is the best way to initialise class members.

The traditional way to initialise looks like this:

class MyClass
{
private:
int a;
public:
MyClass()
: a(5)
{}
};

Though we now have inline initialisers as in your first example, since C++11.



Related Topics



Leave a reply



Submit