In the first case, you are calling the constructors for the fields, and thereby initializing the fields.
In the second case, you first call the default constructors, and if field initializers are missing in their definition, then copy assignment operators are also called to initialize these fields accordingly, which can be very expensive in the end.
Imagine, for example, that memory is dynamically allocated in a constructor. Then this memory will be redefined in the copy assignment operator.
In addition, it may happen that some data member does not have a default constructor at all, but only constructors with parameters. In this case, the second option will not compile at all.
Consider a simple example.
This program will compile successfully.
#include <iostream> struct A { int x; A( int x ) : x( x ) {} }; struct B { A a; B() : a( 10 ) {} }; int main() { return 0; }
However, the following program will not compile
#include <iostream> struct A { int x; A( int x ) : x( x ) {} }; struct B { A a; B() { a = 10; } }; int main() { return 0; }
because there is no default constructor for class A , which must be called before transferring control to the body of constructor B