When exactly is copy constructor called? [duplicate] - c++

This question already has answers here:
c++: MyClass x(1,2,3) vs MyClass x = MyClass(1,2,3)
(1 answer)
What's the difference between Radio r = Radio("PSR", 100.8) and Radio("PSR", 100.8)?
(1 answer)
Shouldn't there be a copy ctor invocation here? Elision disabled (no named return value optimization)
(1 answer)
Copy/Move Constructor is not called when storing result of overloaded operator+
(1 answer)
Closed 7 months ago.
I have the following code:
#include<iostream>
using namespace std;
class A{
private:
int x;
public:
A(){x=10;}
A(int m){x=m; cout << "int m constructor" << m << endl;}
A(A& a){cout << "copy constructor:"<<a.x<<"\n"; x=a.x;}
A(A&& a){cout <<"move constructor:"<<a.x<<"\n"; x=a.x;}
};
int main(){
A a(100);
A b = a;
A d = A(30);
}
which outputs the following:
int m constructor100
copy constructor:100
int m constructor30
I was expecting it to output
int m constructor100
copy constructor:100
copy constructor:30
because the constructor function (A(30)) is called.
But somehow the compiler optimises it?
Also A d = A(A(30)) also prints int m constructor30.
Is there some compiler optimization happening here?

Your last line A d = A(30) and A d = A(A(30)) is the mandatory copy elision.

Related

C++ constructor invocation [duplicate]

This question already has answers here:
How does guaranteed copy elision work?
(2 answers)
What are copy elision and return value optimization?
(5 answers)
Closed 21 days ago.
The following invokes one instance of the constructor followed by the destructor of A (vs. invoking copy or move constructors). Is this an optimization that only one instance of A is created, or is this behavior mandated by the standard?
#include <iostream>
struct A {
A() {
std::cout << "Constructor\n";
}
~A() {
std::cout << "Destructor\n";
}
A (const A&) = delete;
};
int main() {
A a{A{A{A{A{}}}}};
}

Why are templated copy constructors ignored? [duplicate]

This question already has answers here:
Copy constructor of template class
(2 answers)
Why can't I override the default copy constructor and assignment operator with template versions in C++
(2 answers)
Closed 4 years ago.
I think this code should print "hit" but it doesn't. If you comment out line 6 (the template line), it prints "hit."
#include <iostream>
struct test {
test() {}
template<typename = typename std::enable_if<true>::type>
test(test const & other) {
std::cout << "hit";
}
};
int main()
{
test a;
test b(a);
}
The standard explicitly indicates this. What's the rationale?

Multiple constructor called for one object [duplicate]

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

Different behaviour of returning class object from a function [duplicate]

This question already has answers here:
What are copy elision and return value optimization?
(5 answers)
Closed 7 years ago.
The following code
class Foo
{
public:
Foo() {a = 1;};
Foo(const Foo&) :a(2) {};
int a;
};
Foo foo()
{
Foo a;
return a;
}
int main(int argc, char* argv[])
{
Foo f = foo();
std::cout << f.a << std::endl;
return 0;
}
works different on Mac(with g++) and VS2013. On Mac it prints 1, whereas on Windows prints 2. Then why doesn't the program call the copy constructor when foo() returns a class object by value?
This behavior is due to extra copy being elided in MAC. Probably, turning on optimizations in Visual studio would bring similar results.

C++: why constructor "A(A a) {}" is illegal? [duplicate]

This question already has answers here:
Why should the copy constructor accept its parameter by reference in C++?
(9 answers)
Closed 8 years ago.
I met a quiz saying that the code below is ill-formed because "It is illegal to have a constructor whose first and only non-default argument is a value parameter for the class type."
I couldn't understand that. Why things like A(A a) : val (a.val) {} is ruled as illegal? why such a line in the standard? Is it because this will lead to ambiguity with copy constructor?
#include <iostream>
struct A
{
A() : val() {}
A(int v) : val(v) {}
A(A a) : val(a.val) {}
int val;
};
int main(int argc, char** argv)
{
A a1(5);
A a2(a1);
std::cout << a1.val + a2.val << std::endl;
return 0;
}
A(A a) : val(a.val) {} will cause an infinite recursion because constructor arguments are being copied by value (invoking copy constructor and again the copy constructor and ...)
A copy constructor is called when an object is passed by value. Copy constructor itself is a function. So if we pass argument by value in a copy constructor, a call to copy constructor would be made to call copy constructor which becomes a non-terminating chain of calls. Therefore compiler doesn’t allow parameters to be pass by value
Its already discussed on this SO post
Why should the copy constructor accept its parameter by reference in C++?
Everything changes with const:
#include <iostream>
struct A
{
A () : _a(0) {}
A (int a) : _a(a) {}
A (const A& a) : _a(a._a) {}
int _a;
};
int main()
{
A a(5);
A b(10);
A c(a);
std::cout << a._a + b._a + c._a << std::endl; // 20
return 0;
}