Multiple constructor called for one object [duplicate] - c++

This question already has an answer here:
Relationship between assignment operator and user-defined constructor
(1 answer)
Closed 5 years ago.
#include <iostream>
using namespace std;
class A
{
private :
int m_n;
static int copyconst;
static int copydest;
public :
A()
{
cout<<"Default constructor"<<endl;
}
A(int n):m_n(n)
{
cout<<"Param constructor"<<endl;
cout<<m_n<<endl;
}
A(const A&obj1)
{
++copyconst;
cout<<"Copy constructor"<<endl;
}
A& operator=(const A&obj)
{
cout<<"Assignment operator"<<endl;
}
~A()
{
++copydest;
}
};
int A::copyconst = 0;
int A::copydest = 0;
int main()
{
A a = 0;
a = 2;
}
Output -
Param constructor
0
Param constructor
2
Assignment operator
I am not able to understand why I am getting this output can any one help?

I am not able to understand why I am getting this output can any one help?
A a = 0;
is equivalent to:
A a(0);
That explains the first couple of lines of output.
a = 2;
is equivalent to:
a = A(2);
since there is no operator= function whose LHS is an A and the RHS is an int.
That explains the second couple of lines of output and the last line of output.

I believe you understand the first two prints.
Param constructor
0
This is because A a = 0; is a call to the constructor and not the assignment operator (as the object is being constructed)
When you do
a = 2;
then 2 is first converted to an object of type A because A can take int argument and you have not declared the constructor explicit. Hence you see this output
Param constructor
2
Next, the assignment operator is called to assign the value of A(2) to a and hence this output
Assignment operator

Related

why is copy constructor called twice in this code? [duplicate]

This question already has answers here:
std::vector init with braces call copy constructor twice
(2 answers)
Closed 9 months ago.
When I execute the below code, a copy constructor of AAA is called twice between boo and foo.
I just wonder when each of them is called exactly.
Code:
#include <iostream>
#include <vector>
class AAA
{
public:
AAA(void)
{
std::cout<<"AAA ctor"<<std::endl;
}
AAA(const AAA& aRhs)
{
std::cout<<"AAA copy ctor"<<std::endl;
}
AAA(AAA&& aRhs) = default;
};
void foo(std::vector<AAA>&& aVec)
{
std::cout<<"----foo"<<std::endl;
}
void boo(const AAA& a)
{
std::cout<<"----boo"<<std::endl;
foo({a});
std::cout<<"----boo"<<std::endl;
}
int main(void)
{
AAA a;
boo(a);
return 0;
}
Output:
AAA ctor
----boo
AAA copy ctor
AAA copy ctor
----foo
----boo
The copy constructor is invoked twice here:
foo({a});
First to construct the elements of the initializer list, and second to copy the values from the initializer list to the std::vector.

Move constructor should be called by default

In following case where i have created move ctor in Integer class, i am expecting that it should be called by default on rvalue reference while creating Product object but i am getting call of copy constructor only.
Gcc - 7.5.0 on Ubuntu 18
#include<iostream>
using namespace std;
class Integer
{
int *dInt = nullptr;
public:
Integer(int xInt) {
dInt = new int(xInt);
cout<<"Integer Created"<<endl;
}
Integer(const Integer &xObj)
{
cout<<"Copy called"<<endl;
dInt = new int(xObj.mGetInt());
}
Integer(Integer &&xObj)
{
cout<<"Move called"<<endl;
dInt = xObj.dInt;
xObj.dInt = nullptr;
}
Integer& operator=(const Integer &xObj)
{
cout<<"Assignment operator called"<<endl;
*dInt = xObj.mGetInt();
return *this;
}
Integer& operator=(Integer &&xObj)
{
cout<<"Move Assignment operator called"<<endl;
delete dInt;
dInt = xObj.dInt;
xObj.dInt = nullptr;
return *this;
}
~Integer()
{
cout<<"Integer destroyed"<<endl;
delete dInt;
}
int mGetInt() const {return *dInt;}
};
class Product
{
Integer dId;
public:
Product(Integer &&xId)
:dId(xId)
{
}
};
int main ()
{
Product P(10); // Notice implicit conversion of 10 to Integer obj.
}
In above case, move called if i use dId(std::move(xId)) in Product class ctor, I was expecting it should called by default on rvalue reference.
In following case i couldn't avoid creating of temporary object of Integer class, Is there any good way to avoid creating of temporary object.
Product(const Integer &xId)
:dId(xId)
{
}
Product(10); // inside main
My purpose of above question to build my understanding so that i can utilize temporary object memory better.
You need std::move to "propagate" rvalue-reference-ness.
Inside the body of the following function:
void foo(int&& x);
…an expression x is an lvalue int. Not int&&.
References don't really "exist" — even though they are powered by the type system, they are supposed to be treated as aliases (rather than separate entities), so using x inside foo is treated just like using the original, referred-to int inside foo … and doing that would also create a copy, as you know.
This will do the job:
Product(Integer&& xId)
: dId(std::move(xId))
{}
However, I actually encourage you to take Integer by value:
Product(Integer xId)
: dId(std::move(xId))
{}
That way, you can use the same constructor for passing lvalue Integer too, and a copy will be produced if necessary, whereas a move will happen automatically if not (e.g. by passing in a literal, which will automatically trigger selection of Integer's move constructor).

Why is the default constructor the only one being used? [duplicate]

This question already has answers here:
Copy constructor elision?
(2 answers)
Closed 8 years ago.
I am triying to see when each method is called in this example:
#include <iostream>
using namespace std;
class A {
public:
int x;
A(int x) : x(x) {cout<<"default ctor"<<endl;}
A(const A& a) : x(a.x) {cout<<"copy ctor"<<endl;}
A& operator =(const A& a) {cout<<"assignment op"<<endl;x=a.x;return *this;}
};
A f() { return A(5); }
int main() {
A a = f();
}
I expected the copy constructor to be called with the sentence return A(5) because as long as I know when an object is returned a temporary copy is created and returned. And also, in the sentence A a = f() I would expect the copy constructor to be called too because a is being initialized given another A object.
Why is default ctor being printed?
Two optimizations come into play here. Return Value Optimization (RVO)
And Copy Elision will merge f()'s return value directly into the destination variable via initialization. So this code:
A f() { return A(5); }
A a = f();
Optimizes to essentially:
A a(5);
Because c++ compilers are allowed to skip the operator= in cases of
A a = A();
A b = A(a);
and use constructors directly.
They are also allowed to perform Return Value Optimization for copy elision.
So in the end you have essentially A a(5);

C++ overriding the assignment operator

To understand constructor and assignment, I wrote a very simply testing code like this:
class A {
public:
A() { std::cout<<"This is default cstr."; }
A(int i) { std::cout<<"This is int cstr. value is "<<i; }
A(const A &a) { std::cout<<"This is copy cstr."; }
A operator=(const A &a) { std::cout<<"This is assignment operator."; return *this;// this line is tricky }
};
int _tmain(int argc, _TCHAR* argv[]) {
std::cout<<"line 1 "; A a1; std::cout<<std::endl;
std::cout<<"line 2 "; A a2 = A(1); std::cout<<std::endl;
std::cout<<"line 3 "; a1 = a2; std::cout<<std::endl;
return 0;
}
For line 3 I got:
line 3 This is assignment operator.This is copy cstr.
But if I change return *this; to return NULL, I got:
line 3 This is assignment operator.This is int cstr. value is 0
Could someone explain what happened inside for me?
Your operator is returning A instead of A&:
A operator=(const A &a)
So when you return NULL, you are calling the implicit constructor A(int) and passing NULL to it.
The problem
line 3 This is assignment operator.This is copy cstr.
Your code's calling:
A operator=(const A &a) { std::cout<<"This is assignment operator."; return *this;
This obviously prints "This is assignment operator.", then return *this; statement sees the return type of A and creates a return value of type A doing the equivalent of A(*this); -> that calls the copy constructor, explaining this part of the output:
line 3 This is assignment operator.This is copy cstr.
^^^^^^^^^^^^^^^^^^
But if I change return *this; to return NULL, I got:
line 3 This is assignment operator.This is int cstr. value is 0
In this case:
A operator=(const A &a) { std::cout<<"This is assignment operator."; return NULL; }
You end up creating the return value of type A as per A(NULL), and as NULL is 0, that matches the A(int) constructor best, which is why you see:
line 3 This is assignment operator.This is int cstr. value is 0
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The solution
A& operator=(const A &a) { std::cout<<"This is assignment operator."; return *this; }
^
You normally want the assignment operator to return a reference to the *this object. That way, no additional A object is constructed as the assignment operator function returns.
Aside - why return `A&` anyway?
The reason A& is returned and not void, is that it allows further chained use of the object, as in:
a1 = a2 = a3;
Which is evaluated as:
a1.operator=(a2.operator=(a3));
Is a2.operator= returned void then there'd be no usable argument to a1.operator=().
A non-const reference supports usage like:
make_uppercase(my_string = other_string);
In some other languages, that would need to be broken into two statements. Whether you wish it was depends on whether you find it confusing, and how much you value concision.
Your code says
A operator = (const A& a)
You take a reference to an A, you modify yourself, and then you return A(*this) which invokes the copy-constructor to create a new instance and return by value.
What you probably intended was
A& operator = (const A& a)
This will then return a reference to *this rather needing to copy it into a new temporary instance.
Be aware that NULL is a macro alias for '0UL' or '0ULL' which the compiler detects as being a match for A(int). This is one of the reasons that C++11 introduced nullptr as an alternative to NULL.

Copy constructor not being called [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Copy Constructor is not invoked
# include <iostream>
using namespace std;
class Abc
{
public:
int a;
Abc()
{
cout<<"def cstr\n";
a=10;
}
Abc(const Abc &source)
{
a=source.a;
cout<<"copy constructor is called"<<endl;
}
};
int main()
{
Abc kk = Abc();
cout<<kk.a<<endl;
return 0;
}
In the above program my output is :
def cstr
10
Here I expected that copy constructor would be called after the default contructor which is not happening.
Please tell me whats going on here. Is it because Abc() is creating a temp object ??
Please correct me if I am wrong.
thanks !!!
Your copy constructor is ok, try that
int main() {
Abc kk;
Abc kk1 = kk;
cout<<kk.a<<endl;
return 0;
}
Copy constructor is called once on construction from another existing object. Other times assignment operator is called. By saying Abc kk = Abc(); you are just calling default constructor.