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.
Related
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
This question already has answers here:
Why do I have to call move on an rvalue reference?
(2 answers)
Rvalue Reference is Treated as an Lvalue?
(4 answers)
Closed 5 years ago.
In the following (borrowed) example, in my environment the move constructor is never called:
#include <iostream>
class MyClass {
public:
MyClass()
{
std::cout << "default constructor\n";
}
MyClass(MyClass& a)
{
std::cout << "copy constructor\n";
}
MyClass(MyClass&& b)
{
std::cout << "move constructor\n";
}
};
void test(MyClass&& temp)
{
MyClass a(MyClass{}); // calls MOVE constructor as expected
MyClass b(temp); // calls COPY constructor...
}
int main()
{
test(MyClass{});
return 0;
}
My output is:
default constructor
default constructor
copy constructor
I use XCode version 9.1, shouldnt the move constructor be called on rvalue references? What am I missing here?
John.
What am I missing here?
The point is that everything that has a name is lvalue.
It means that named rvalue reference itself is lvalue and temp from:
void test(MyClass&& temp)
is lvalue as well. So move constructor is not called.
If you want a move constructor to be called, use std::move:
void test(MyClass&& temp)
{
// ...
MyClass b(std::move(temp)); // use std::move here
}
By the way,
MyClass(MyClass& a)
{
std::cout << "copy constructor\n";
}
is not a copy constructor because copy constructor has a form of:
MyClass(const MyClass& a) { ... }
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;
}
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);
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.