Copy constructor when declaring two objects - c++

Does declaring the following:
MyClass myFirstObject;
MyClass mySecondObject = myFirstObject;
mean that the copy constructor is used for the second object even if no parameter is passed?

Yes,A copy constructor is used to initialize an object with a differnt object of same type.
Situation where a copy constructor is called
MyClass A;
MyClass B(A); //Explicit Copy constructor invoked
MyClass C = A; //Implicit Copy constructor invoked

An easy way to check is by adding a cout statement in the copy constructor:
MyClass::MyClass(const MyClass&){
std::cout << "I am called!";
/*do stuff*/
}

Related

Am I calling the constructor or the copy constructor? [duplicate]

I don't understand the difference between assignment constructor and copy constructor in C++. It is like this:
class A {
public:
A() {
cout << "A::A()" << endl;
}
};
// The copy constructor
A a = b;
// The assignment constructor
A c;
c = a;
// Is it right?
I want to know how to allocate memory of the assignment constructor and copy constructor?
A copy constructor is used to initialize a previously uninitialized object from some other object's data.
A(const A& rhs) : data_(rhs.data_) {}
For example:
A aa;
A a = aa; //copy constructor
An assignment operator is used to replace the data of a previously initialized object with some other object's data.
A& operator=(const A& rhs) {data_ = rhs.data_; return *this;}
For example:
A aa;
A a;
a = aa; // assignment operator
You could replace copy construction by default construction plus assignment, but that would be less efficient.
(As a side note: My implementations above are exactly the ones the compiler grants you for free, so it would not make much sense to implement them manually. If you have one of these two, it's likely that you are manually managing some resource. In that case, per The Rule of Three, you'll very likely also need the other one plus a destructor.)
The difference between the copy constructor and the assignment operator causes a lot of confusion for new programmers, but it’s really not all that difficult. Summarizing:
If a new object has to be created before the copying can occur, the copy constructor is used.
If a new object does not have to be created before the copying can occur, the assignment operator is used.
Example for assignment operator:
Base obj1(5); //calls Base class constructor
Base obj2; //calls Base class default constructor
obj2 = obj1; //calls assignment operator
Example for copy constructor:
Base obj1(5);
Base obj2 = obj1; //calls copy constructor
The first is copy initialization, the second is just assignment. There's no such thing as assignment constructor.
A aa=bb;
uses the compiler-generated copy constructor.
A cc;
cc=aa;
uses the default constructor to construct cc, and then the *assignment operator** (operator =) on an already existing object.
I want know how to allocate memory of the assignment constructor and copy constructor?
IDK what you mean by allocate memory in this case, but if you want to see what happens, you can:
class A
{
public :
A(){ cout<<"default constructor"<<endl;};
A(const A& other){ cout<<"copy constructor"<<endl;};
A& operator = (const A& other){cout <<"assignment operator"<<endl;}
};
I also recommend you take a look at:
Why is copy constructor called instead of conversion constructor?
What is The Rule of Three?
In a simple words,
Copy constructor is called when a new object is created from an existing object, as a copy of the existing object.
And assignment operator is called when an already initialized object is assigned a new value from another existing object.
Example-
t2 = t1; // calls assignment operator, same as "t2.operator=(t1);"
Test t3 = t1; // calls copy constructor, same as "Test t3(t1);"
What #Luchian Grigore Said is implemented like this
class A
{
public :
int a;
A(){ cout<<"default constructor"<<endl;};
A(const A& other){ cout<<"copy constructor"<<endl;};
A& operator = (const A& other){cout <<"assignment operator"<<endl;}
};
void main()
{
A sampleObj; //Calls default constructor
sampleObj.a = 10;
A copyConsObj = sampleObj; //Initializing calls copy constructor
A assignOpObj; //Calls default constrcutor
assignOpObj = sampleObj; //Object Created before so it calls assignment operator
}
OUTPUT
default constructor
copy constructor
default constructor
assignment operator
the difference between a copy constructor and an assignment constructor is:
In case of a copy constructor it creates a new object.(<classname> <o1>=<o2>)
In case of an assignment constructor it will not create any object means it apply on already created objects(<o1>=<o2>).
And the basic functionalities in both are same, they will copy the data from o2 to o1 member-by-member.
I want to add one more point on this topic.
"The operator function of assignment operator should be written only as a member function of the class." We can't make it as friend function unlike other binary or unary operator.
Something to add about copy constructor:
When passing an object by value, it will use copy constructor
When an object is returned from a function by value, it will use copy constructor
When initializing an object using the values of another object(as the example you give).

Has the compiler defined assign operator to call the copy constructor?

The rule-of-three is well known and says that if one has to define a destructor, so one has most probably to define a copy constructor and an assignment operator.
However, recently in some code, I stumbled upon a "rule-of-two": Only the destructor and the copy constructor were defined and the assign operator was left for compiler to define. My first thought was "this must be an error", but now I'm not that sure, because all compilers (gcc, msvs, intel) produced assignment operator which called the copy constructor.
Simplified, the class looks as follows:
struct A{
size_t size;
int *p;
A(size_t s): size(s), p(new int[size]){}
A(const A&a): size(a.size), p(new int[size]){
std::copy(a.p, a.p+a.size, p);
std::cout<<"copy constructor called\n";
}
~A(){
delete[] p;
}
};
And used like this:
int main(){
A a(2);
a.p[0]=42.0;
A b=a;
std::cout<<"first: "<<b.p[0]<<"\n";
}
produces the following output:
copy constructor called
first: 42
My question: It is guarantied, that the compiler defined assignment operator will call the copy constructor, or it is only a lucky coincidence, that all compilers do it that way?
Edit: It's true, I confused initialization and assignment! Replacing A b=a; by A b(0); b=aleads as expected to a double-free-error.
It's you who misunderstands what's happening, there is no assignment at all going on, only construction and initialization.
When you do
A b = a;
there's no assignment, only initialization. More precisely copy initialization. It's the same as writing
A b(a);
Initialization create a new object:
A a; // initialization
A b(a); // initialization
A c = a; // initialization
Assignment modifies an existing object:
A a;
a = 3; // assignment
In the code example, as various comments have said, there is no assignment being done; all of the examples are initializations, so the compiler-generated assignment operator is not used.

Difference between the move assignment operator and move constructor?

For some time this has been confusing me. And I've not been able to find a satisfactory answer thus far. The question is simple. When does a move assignment operator get called, and when does a move constructor operator get called?
The code examples on cppreference.com yield the following interesting results:
The move assignment operator:
a2 = std::move(a1); // move-assignment from xvalue
The move constructor:
A a2 = std::move(a1); // move-construct from xvalue
So has it do to with which is implemented? And if so which is executed if both are implemented? And why is there the possibility of creating a move assignment operator overload at all, if it's identical anyway.
A move constructor is executed only when you construct an object. A move assignment operator is executed on a previously constructed object. It is exactly the same scenario as in the copy case.
Foo foo = std::move(bar); // construction, invokes move constructor
foo = std::move(other); // assignment, invokes move assignment operator
If you don't declare them explicitly, the compiler generates them for you (with some exceptions, the list of which is too long to be posted here).
See this for a complete answer to when the move member functions are implicitly generated.
When does a move assignment operator get called
When you assign an rvalue to an object, as you do in your first example.
and when does a move constructor operator get called?
When you initialise an object using an rvalue, as you do in your second example. Although it isn't an operator.
So has it do to with which is implemented?
No, that determines whether it can be used, not when it might be used. For example, if there's no move constructor, then construction will use the copy constructor if that exists, and fail (with an error) otherwise.
And if so which is executed if both are implemented?
Assignment operator for assignment, constructor for initialisation.
And why is there the possibility of creating a move assignment operator overload at all, if it's identical anyway.
It isn't identical. It's invoked on an object that already exists; the constructor is invoked to initialise an object which previously didn't exist. They often have to do different things. For example, assignment might have to delete something, which won't exist during initialisation.
This is the same as normal copy assignment and copy construction.
A a2 = std::move(a1);
A a2 = a1;
Those call the move/copy constructor, because a2 doesn't yet exist and needs to be constructed. Assigning doesn't make sense. This form is called copy-initialization.
a2 = std::move(a1);
a2 = a1;
Those call the move/copy assignment operator, because a2 already exists, so it doesn't make sense to construct it.
Move constructor is called during:
initialization: T a = std::move(b); or T a(std::move(b));, where b is of type T;
function argument passing: f(std::move(a));, where a is of type T and f is void f(T t);
Move assignment operation is called during:
function return: return a; inside a function such as T f(), where a is of type T which has a move constructor.
assignment
The following example code illustrates this :
#include <iostream>
#include <utility>
#include <vector>
#include <string>
using namespace std;
class A {
public :
A() { cout << "constructor called" << endl;}
~A() { cout << "destructor called" << endl;}
A(A&&) {cout << "move constructor called"<< endl; return;}
A& operator=(A&&) {cout << "move assignment operator called"<< endl; return *this;}
};
A fun() {
A a; // 5. constructor called
return a; // 6. move assignment operator called
// 7. destructor called on this local a
}
void foo(A){
return;
}
int main()
{
A a; // 1. constructor called
A b; // 2. constructor called
A c{std::move(b)}; // 3. move constructor called
c = std::move(a); // 4. move assignment operator called
a = fun();
foo(std::move(c)); // 8. move constructor called
}
Output :
constructor called
constructor called
move constructor called
move assignment operator called
constructor called
move assignment operator called
destructor called
move constructor called
destructor called
destructor called
destructor called
destructor called

copy constructor VS constructor with a class pointer as parameter

Q1: Does the "self class typed pointer constructor" have a decent/official name?
Q2: Why is copy constructor much more famous than "self class typed pointer constructor"?
Or what are the cases that we must use copy constructor rather then "self class typed pointer constructor"?
class MyClass
{
public:
int i;
MyClass()
{
i = 20;
}
//Copy constructor
MyClass(MyClass const & arg)
{
i = arg.i;
}
//What kind of Constructor is this one?
MyClass(MyClass* pArg)
{
i = pArg->i;
}
};
int main() {
MyClass obj;
MyClass* p = new MyClass();
//call copy constructor
MyClass newObj(obj); //call copy constructor directly
MyClass newObj2(*p); //dereference pointer and then call copy constructor
MyClass* pNew = new MyClass(*p); //dereference pointer and then call copy constructor
//Call THE constructor
MyClass theObj(&obj); //get the address, call THE constructor
MyClass theObj2(p); //call pointer constructor directly
MyClass* ptheNew = new MyClass(p); //call pointer constructor directly
}
It has no special name, because there is nothing special about it.
The copy constructor is "more famous", because it is special. It is special because it is a fundamental part of the way the language works. If you don't declare a copy constructor, in most classes, one will be implicitly defined for you. It is involved in many basic operations, such as these:
void foo(MyClass obj) // the copy ctor is (potentially) called to create this parameter
{
...
}
MyClass bar() // the copy ctor is (potentially) called when this function returns, and when it result is used
{
...
}
MyClass a;
MyClass b(a); // This calls the copy constructor
MyClass c = b; // So does this
Note that, in many cases, the copy is optimized away. See Copy Elision. Also, in C++11, the move constructor is called in many places where the copy constructor used to be called. But the move constructor too can be optimized away in the same places that copy elision could happen.
I can't think of many reasons you would ever use "THE constructor", as you call it.
On a side note, a copy constructor should almost always have this signature:
MyClass(MyClass const &)
Not this one:
MyClass(MyClass &)
To an object in C++, we usually use reference rather than pointer. We can use reference to get the address of the object, and than you can use '.' to access its method or data, it is more simple and direct than '->'.
I think there is no need to use 'THE constructor'.

Copy constructor invocation for member objects

C++ says that to create a copy constructor for a class that uses composition, the compiler recursively calls the copy constructors for all the member objects. I tried that same thing in the below code:
class A
{
public:
A(){cout<<"A constructor called"<<endl;}
A(const A&){cout<<"A copy constructor called"<<endl;}
};
class B
{
public:
B(){cout<<"B constructor called"<<endl;}
B(const B&){cout<<"B copy constructor called"<<endl;}
};
class C
{
A a;
B b;
public:
C(){cout<<"C constructor called"<<endl;}
C(const C&){cout<<"C copy constructor called"<<endl;}// If you comment this line, you will get output: Case 1 (see below) and if you don't comment, you will get o/p: case 2(see below)
};
void main()
{
C c;
cout<<endl;
C c2 = c;
}`
Case 1:
A constructor called
B constructor called
C constructor called
A copy constructor called
B copy constructor called
Case 2:
A constructor called
B constructor called
C constructor called
A constructor called
B constructor called
C copy constructor called
My doubt is that the o/p for case 2 should be: A, B, C, constructor called and then.. A, B, C copy constructor called. But it is not happening. Please help.
That would happen, except that you have provided your own copy constructor for C, which tells the compiler "don't provide the default copy constructor."
If you want your copy constructor to do the same thing that the implicitly defined copy constructor would do (along with your extra printing), you'd need to define it as follows:
C(const C& other)
: a(other.a), b(other.b)
{
std::cout << "C copy constructor called" << std::endl;
}
The standard is only explaining behavior for the default copy constructor. The default copy constructor is the one you're using when you comment out the copy constructor you wrote for C. If you write your own copy constructor you must explicitly copy any members you wish to copy, like so:
C( const C& c ) : a(c.a), b(c.b) {cout<<"C copy constructor called"<<endl;}
Obivously writing your own copy constructor is somewhat error prone, so it's best to rely on the default one whenever possible.
In both cases, C::C( C const &) copy constructor is called. When it is implicit, then it calls copy constructors of base classes. When it is explicit the way you define it, it calls default constructors of A and B. This is expected behavior. Note, C c2 = c; is equal to C c2(c);, there is no temporaries.