-2

I read a few different topics on these forums and I'm not getting a clear answer on it.

I have two questions, what is the difference between a default/base construct and a construct initialize list? They look the same to me, here are my examples. Do I have them commented correctly as well as what they are?

//In my .h file:
class Complex {

public:
Complex();
Complex(double, double);
private:
double real;
double imag;
};

//In my implementation file:
Complex::Complex() :real(NULL), imag(NULL) // initialization list
{
}

Complex::Complex(double inReal, double inImag) // default constructor
{
real = inReal;
imag = inImag;
}    
Smith John
  • 25
  • 7
  • Possible duplicate of [Initializing fields in constructor - initializer list vs constructor body](https://stackoverflow.com/questions/9903248/initializing-fields-in-constructor-initializer-list-vs-constructor-body) – Rietty Feb 06 '19 at 22:53
  • 2
    It doesn't make sense to initialise `double` variables with `NULL`. –  Feb 06 '19 at 22:53
  • 2
    `real(NULL), imag(NULL)` Do not do this. `NULL` is for pointers. If you are using C++11 stop using `NULL` and use `nullptr` instead. For things that aren't pointers, you can just use `()` to value initialize them. – NathanOliver Feb 06 '19 at 22:53
  • 1
    Also you should probably move away from `()` in initializer lists in general and prefer `{}` but that's an argument for semantics mostly. – Rietty Feb 06 '19 at 22:55
  • Will make those changes. But do I have them labeled correctly? Is the first one my initialization list and the 2nd my default? – Smith John Feb 06 '19 at 23:00

2 Answers2

1

In this case,

Complex::Complex() : real(NULL), imag(NULL)
{
}

would be your default constructor, because it is the one here that has no parameters.

An initializer list is what you see following your default constructor's name, being

:real(NULL), imag(NULL)

This is a list of member initializations that take place upon calling the default constructor Complex::Complex()

As an aside, NULL is a value meant to represent a pointer that does not point to any valid addressable memory location. It's not exactly applicable to double types.

Elenchus
  • 482
  • 3
  • 4
  • Thank you, this is the explanation I was looking for. A few questions about this then. If my default constructor is also my initialization list, what is the point of my second constructor? Is it needed? And if the second constructor is not my default, what is it's technical name? – Smith John Feb 06 '19 at 23:07
  • 1
    @SmithJohn The default constructor is whichever constructor takes no parameters. How it's implemented is immaterial. In your case, you're using an initialization list as the implementation, which is good. But those are unrelated concepts. Your second constructor is just another constructor with two parameters. There's no technical name for those. – Mooing Duck Feb 06 '19 at 23:09
  • Thank you Mooing Duck, I appreciate the information/response. – Smith John Feb 06 '19 at 23:17
1

I have two questions, what is the difference between a default/base construct and a construct initialize list?

A default constructor is a constructor that will be invoked when you create an object but don't specify any constructor arguments. For example, all these variables will be initialised by a call to the default constructor:

Complex myComplex1;
Complex myComplex2();
Complex myComplex3{};

Some other constructors do require arguments, so they're not default constructors.

In the implementation of any constructor (whether a default constructor or not) for an object with bases or member variables or constants, you can use an initialisation list to construct/initialise those bases or members.

They look the same to me, here are my examples. Do I have them commented correctly as well as what they are?

You didn't have them commented correctly. A fixed version is:

Complex::Complex()  // default constructor as it does not require args
   : real{}, imag{} // initialization list: sets both to 0.0
{ }

Complex::Complex(double inReal, double inImag) // NOT a default constructor
                                               // as it requires arguments
  : real(inReal), imag(inImag)  // initialisation list
{
    // real = inReal;  // set in the initialisation list instead
    // imag = inImag;
}

The non-default constructor above is invoked when you create an object while specifying matching constructor arguments:

Complex myComplex4(3.1, 2);
Complex myComplex5{-2.3, 2.7};

It's a good idea to preferentially use an initialisation list to construct your bases and set your members: otherwise at best they'll be default initialised then assigned to, which can be less efficient, but for references and constants you simply have to use an initialisation list.


It is possible to create a default constructor with arguments with default values:

Complex(double inReal = 0.0, double inImag = 0.0)
  : real(inReal), imag(inImag)
{ }

This single constructor can reasonably replace both the constructors in your code.

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
  • 1
    I really appreciate this comment/the information you provided. I bookmarked this and will show it to my friends in class as well who were confused about this as well. – Smith John Feb 07 '19 at 01:19