0

I am following two different C++ programming courses. One is a mandatory course from my Physics degree, ROOT-oriented, and one is a course from the Informatics degree I chose on my own.

The problem is, the examples they give for constructors in classes are slightly different.

Let's pick, for example, the default ctor for a class named CDate, containing three ints, one for the day, one for the month, and one for the year. If nothing is passed to initialize the date, it is automatically set to the first of January, 1900.

The slide from the Informatics course gives this example:

CDate::CDate(void){
mDay=1;
mMonth=1;
mYear=1900;
}

While the one from my Physics course gives this:

CDate::CDate():
mDay (1),
mMonth (1),
mYear (1900)
{}

They only put things inside the braces if they have to modify some variables already created outside the braces.

Let's say, for example, we want to create a class representing an histogram, giving the minimum value, the maximum one, the number of bins, and then an array containing the values inside every single bin. The complete constructor would look like this:

histogram::histogram (const int &nBin, const float &min, const float &max):
 nBin_p (nBin),
 min_p (min),
 max_p (max),
 binContent_p ( new int[nBin_p] )
{
  //initialize to zero the bin content
  for (int i = 0; i < nBin_p; ++i)
    binContent_p[i] = 0;
}

(the variables with _p are the actual ones of the class, defined as private in the class implementation).

I guess the "better" one is the one by the Informatics, they should know better, right?But still, I wonder, what are in a nutshell the actual differences between the two ways, as slight as they can be? When should I better use one and when the other one, or are they completely equivalent?

Jeffrey Lebowski
  • 281
  • 1
  • 2
  • 12
  • 3
    No, the "better" one is the Physics one. It is initialization (Physics) versus assignment (informatics). The presence of a `void` parameter in the first version should raise a flag. – juanchopanza Feb 20 '15 at 11:18
  • @juanchopanza You mean the difference between `mDay=1` and `mDay (1)`, right? But can the first be done outside the braces and the second inside, too, or must assignments be included between braces and initializations be outside? Also, in the second part, do you mean that writing `(void)` instead of just `()` is useless and a waste of space, or something else? – Jeffrey Lebowski Feb 20 '15 at 11:22
  • You must read this: http://stackoverflow.com/questions/926752/why-should-i-prefer-to-use-member-initialization-list – CinCout Feb 20 '15 at 11:22
  • 2
    @JeffreyLebowski Not quite. It is the difference between `int n = 42;` (physics) and `int n; n = 42;` (informatics). Note that `int n = 42;` and `int n(42);` are largely equivalent and are both initializations. – juanchopanza Feb 20 '15 at 11:23
  • http://stackoverflow.com/questions/1711990/what-is-this-weird-colon-member-syntax-in-the-constructor?rq=1 – Lightness Races in Orbit Feb 20 '15 at 11:45

3 Answers3

1

The one from your Physics example is called a initialization list, it's the preferred way to initialize member variables. see here for more explanation.

swang
  • 5,157
  • 5
  • 33
  • 55
1

The informatics' approach actually sounds very C-derived, they do not take advantage of some C++ "pecularities". They just do some assignments to those member variables.

The physics rather do initialization. At first sight the difference might only seem aesthetic, and probably won't make much of a difference in practice as long as the member variables you are initializing are fundamental types.

But what if you have a member variable that is of an object type and which does not have a void constructor? To invoke a constructor with arguments for that type you can only use the Physics' approach (which is called initialization list, by the way).

SukkoPera
  • 621
  • 4
  • 8
-1

The second syntax is the only option for initializing member object-variables (it's really a constructor call). For simple types, such as int, long, etc., there is only small difference in execution order, which could be always fixed by hand.

Matt
  • 13,674
  • 1
  • 18
  • 27
  • It is not "really a constructor call" in the slightest. – Lightness Races in Orbit Feb 20 '15 at 11:45
  • @LightnessRacesinOrbit Why not? – Matt Feb 20 '15 at 11:53
  • What do you mean why not? Because it simply isn't. It's initialisation syntax. Despite appearances, it's no more a constructor call than is the expression `T(5)` that creates a temporary of type `T`. The only time you can invoke a constructor directly is like `Base::Base()` from inside `Derived::Derived()`. – Lightness Races in Orbit Feb 20 '15 at 12:04
  • @LightnessRacesinOrbit It _is_ the constructor call, because the corresponding code will be actually executed, which is easy to find out either by debugging or disassembling. Likewise the expression `T(5)` which creates a temporary of type `T` is no more than allocating some memory and invoking the constructor (and, perhaps, destructor too). – Matt Feb 20 '15 at 12:14
  • No, sorry but that's complete nonsense. You're delving into implementation details, yet we're discussing the _language_. And you yourself just admitted that `T(5)` is not simply a constructor call; the fact that it results in _other_ effects too (such as the initial allocation) is all the proof you need that the syntax is something else. In this case, it's an explicit conversion in functional cast notation. It will _involve_ an invocation of the constructor, but to say that it _is_ a constructor call is plain wrong. Same for your initialisations. – Lightness Races in Orbit Feb 20 '15 at 12:24
  • @LightnessRacesinOrbit `T(5)` is sometimes not only a ct call, as we both know. But so-called "initialization syntax" is. It is only ct call and nothing more than ct call, when it comes to objects. Here calling ct is not "the implementation detail" but the only implementation possible. Thus, stating that there is something else, is just multiplying entities beyond necessity. – Matt Feb 20 '15 at 12:47
  • No, still wrong. Read the syntax grammar. Read the description of the semantics. And then consider that `int`, for example, doesn't even _have_ a constructor. With those three things in concert your assertion just evaporates. – Lightness Races in Orbit Feb 20 '15 at 12:48
  • This only proves that C++ badly distinguishes assignments and ct's. – Matt Feb 20 '15 at 16:24
  • Nonsense. It proves that you do not understand the language and cannot admit it! – Lightness Races in Orbit Feb 20 '15 at 16:36
  • First, try to find in the dictionary the item "politeness" and read it twice. Second, try to get used to understanding, that every one should learn all his life, and should never say the doubtful things in a such peremptory tone. – Matt Feb 20 '15 at 16:54
  • First, you are not my mother. Second, you are the one rejecting the facts here without any basis! I suggest you begin there if you want one of us to embark on some journey of self-improvement. What you're saying _is_ nonsense; now I don't mean to attack your character by that, I'm just stating a plain fact. Please don't take it personally. – Lightness Races in Orbit Feb 20 '15 at 17:02
  • The fact is, C++ freely allows dt's call, but not ct's. To have worked it around, they "invented" some syntax which allows free mixing of member's assignments, member's ct() calls and base's ct() calls without any particular order. The pure fact, that this beast has a name of its own, doesn't make it to be anything more than a placeholder for ct's() calls, which are not allowed inside braces due to language idiosyncrasy. – Matt Feb 20 '15 at 17:40
  • Might as well be saying "iggle wiggle wobble bobble" mate – Lightness Races in Orbit Feb 20 '15 at 17:43
  • It seems that you haven't read the dictionary, even after I asked you. So, the wonderful journey of self-improvement is still in the very beginning. That's a pity. – Matt Feb 20 '15 at 17:52