1

Is there a difference between Demo1 and Demo2 in the following code?

#include <iostream>

class Base {};

class Demo1 : public Base {
public:
    Demo1() : instance_variable(5) {

    }

    int instance_variable;
};

class Demo2 : public Base {
public:
    Demo2() {
        this->instance_variable = 5;
    }

    int instance_variable;
};

int main(int argc, char **argv) 
{    
    Demo1 a;    
    Demo2 b;

    std::cout << "a.instance_variable: " << a.instance_variable << std::endl;
    std::cout << "b.instance_variable: " << b.instance_variable << std::endl;

    return 0;
} 

I saw the first notation in a book I am reading right now, and I am not sure if the two are equivalent or if Demo1 has subtle differences I should be aware of.

I find the second much more readable as I am coming from a Java/JavaScript background, so I am curious if I can replace "Demo1" with "Demo2" without changing the meaning of the code.

Also, what is the expression "constructor:field(x){}" called?

Dmytro
  • 5,068
  • 4
  • 39
  • 50
  • I suggest you read this: http://stackoverflow.com/questions/6822422/c-where-to-initialize-variables-in-constructor – MerajA Sep 10 '16 at 15:59
  • @SauravSahu Thanks that's it! But is it equivalent? Post the answer so I can accept it. – Dmytro Sep 10 '16 at 16:02
  • 1
    Your welcome. I would suggest you to go through the link http://www.geeksforgeeks.org/when-do-we-use-initializer-list-in-c/ as it lists all its usage pointwise. – Saurav Sahu Sep 10 '16 at 16:08
  • 1
    BTW, you don't need to use the `this->` notation; this is not C# nor Java, but C++. Save typing time and lower the risk of injecting defects. Refrain from typing `this->`. Change parameter names or member names if necessary. – Thomas Matthews Sep 10 '16 at 16:19

5 Answers5

6

There can be a difference. As a result the first approach, the constructor initializer syntax, is considered better.

In Demo2, everything gets default-initialized and then the operator= is used to give the new value. Since your instance_variable is just an int, this doesn't matter. But it will matter if:

  • the default constructor, operator=, or both are computationally expensive
  • there is no default constructor
  • the variable is const or a reference, meaning you can't use operator= to change the value
  • the variable is an instance of a class that has been written counter-intuitively, so that you actually get different results from a constructor that takes an argument than from a default constructor followed by assignment. While such classes shouldn't exist, that doesn't mean they don't.

Since the Demo1 way is sometimes faster (never slower) and works in cases where the Demo2 way doesn't, it is the preferred technique. While it may feel unusual to those coming from other languages, it is the way you should write your constructors.

Kate Gregory
  • 18,808
  • 8
  • 56
  • 85
1

If you have a programming background (as you said, you have), you should be well aware of the difference between initializing value to variable and assignment of a value to some variable.

Demo1 is using the variable initialization (instance_variable is being initialized in the member initializer list, Demo() : instance_variable(5)), but Demo2 is assigning value to the instance_variable

I am not sure if the two are equivalent or if Demo1 has subtle differences I should be aware of.

No. The two aren't equivalent.

  • Demo1 is initializing the instance_variable, it means copy constructor will be called (in the case, when instance_variable is object).
  • But the Demo2 is assigning value to the variable after it has been initialized (default constructor has been called, and now operator= will be called to copy values)

Also, what is the expression constructor:field(x){} called?

It's called member initializer list.

EDIT

Member initializer list only makes a difference when initializing objects, but in case of primitives, both ways (Demo1 and Demo2), they're pretty much the same.

And there's another thing that you should know, is, that you'll have to use member initializer list to initialize:

  • const data members
  • member reference variables
  • initializing those member variables (objects of some class), which don't have any default constructor.
  • and when passing parameters to base class constructor.
Ahmad Khan
  • 2,655
  • 19
  • 25
  • So the main difference between them comes into play when the instance variable is an object rather than a primitive? Are they equivalent in the case of primitives(there is no destruction, it just goes out of scope)? – Dmytro Sep 10 '16 at 17:08
  • 1
    The extra overhead will be in case of objects, yes. But in case of primitives, they're pretty much the same. – Ahmad Khan Sep 10 '16 at 17:35
0

Demo1 uses a member initializer list. It calls the constructor of instance_variable with the argument 5.

Demo2 uses the copy assignment operator of instance_variable with the argument 5.

In your case, since instance_variable is an int, there is no difference. However, if instance_variable was some object of a class that behaves differently on initialization and copy assignment, there would be a difference.

Nelfeal
  • 12,593
  • 1
  • 20
  • 39
0
  1. this is called "member initialization"
  2. for and int it makes no difference. for complex object, the member init will call the member's c-tor once with the needed params, instead of calling the default cotr and then setting up the properties manually.
Imbar M.
  • 1,074
  • 1
  • 10
  • 19
0

Using Member Initializer list (demo 1):

A.) Copy constructor of the variable is called as instance_variable(value). B.) Destructor is called when value goes out of scope.

copy constructor + destructor call

Initialization inside constructor block (demo 2): A.) Copy constructor of the variable is called as instance_variable(value). B.) Assignment operator call inside constructor body. C.) Destructor is called when value goes out of scope.

constructor + one addition assignment operator call(for complex and Non-PODs) + destructor 

This assignment penalty will be much more in “real” applications where there will be many such complex objects to initialize. You are doing int assignment, so no difference IMO.

Read more.

Saurav Sahu
  • 13,038
  • 6
  • 64
  • 79