Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constructor being called multiple times

Tags:

c++

I wrote the following c++ code trying to understand copy elision in c++.

#include <iostream>
using namespace std;

class B
{
  public:  
  B(int x  ) //default constructor
  {
    cout << "Constructor called" << endl;
  }    

  B(const B &b)  //copy constructor
  {
     cout << "Copy constructor called" << endl;
  } 
};

int main()
{ 

  B ob =5; 
  ob=6;
  ob=7;

  return 0;
}

This produces the following output:

Constructor called
Constructor called
Constructor called

I fail to understand why is the constructor being called thrice with each assignment to object ob.

like image 987
Abhay Sharma Avatar asked Mar 04 '26 06:03

Abhay Sharma


2 Answers

B ob =5;

This uses the given constructor.

ob=6;

This uses the given constructor because there is not a B& operator=(int) function and 6 must be converted to type B. One path to do this is to temporarily construct a B and use it in the assignment.

ob=7;

Same answer as above.

I fail to understand why is the constructor being called thrice with each assignment

As I stated above you do not have a B& operator=(int) function but the compiler is happy to provide a copy assignment operator (i.e., B& operator=(const B&);) for you automatically. The compiler generated assignment operator is being called and it takes a B type and all int types can be converted to a B type (via the constructor you provided).

Note: You can disable the implicit conversion by using explicit (i.e., explicit B(int x);) and I would recommend the use of explicit except when implicit conversions are desired.

Example

#include <iostream>

class B
{
public:
    B(int x) { std::cout << "B ctor\n"; }

    B(const B& b) { std::cout << B copy ctor\n"; }
};

B createB()
{
    B b = 5;
    return b;
}

int main()
{
    B b = createB();

    return 0;
}

Example Output

Note: Compiled using Visual Studio 2013 (Release)

B ctor

This shows the copy constructor was elided (i.e., the B instance in the createB function is triggered but no other constructors).

like image 85
James Adkison Avatar answered Mar 06 '26 18:03

James Adkison


Each time you assign an instance of the variable ob of type B an integer value, you are basically constructing a new instance of B thus calling the constructor. Think about it, how else would the compiler know how to create an instance of B if not through the constructor taking an int as parameter?

If you overloaded the assignment operator for your class B taking an int, it would be called:

B& operator=(int rhs)
{
    cout << "Assignment operator" << endl;
}

This would result in the first line: B ob = 5; to use the constructor, while the two following would use the assignment operator, see for yourself:

Constructor called
Assignment operator
Assignment operator

http://ideone.com/fAjoA4

If you do not want your constructor taking an int to be called upon assignment, you can declare it explicit like this:

explicit B(int x)
{
    cout << "Constructor called" << endl;
}

This would cause a compiler error with your code, since it would no longer be allowed to implicitly construct an instance of B from an integer, instead it would have to be done explicitly, like this:

B ob(5);

On a side note, your constructor taking an int as parameter, is not a default constructor, a default constructor is a constructor which can be called with no arguments.

like image 32
Tommy Andersen Avatar answered Mar 06 '26 20:03

Tommy Andersen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!