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.
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.
#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;
}
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).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With