Having this class:
class A
{
int number;
int number2;
public:
A(int _number):number(_number),number2(0)
{
cout<<"Normal constructor\n";
}
A()
{
cout<<"Default constructor\n";
}
A(const A& source)
{
number = source.number;
number2 = source.number2;
cout<<"Copy constructor\n";
}
A & operator=(const A& source)
{
number = source.number;
number2 = source.number2;
cout<<"Assignment operator\n";
return *this;
}
};
If vector<A> obj {1,2,3}
is created, normal constructor
is called three times because it is not declared as explicit
and therefore it is used as a converting constructor
. Then the copy constructor
is called three times.
vector
can be declared and instantiated while skipping the copying operation? If vector<A> obj_1;
is executed, an empty vector which can hold objects of type A
is created - no constructors called , but the object exists .
From this link :
A copy constructor is used to initialize a previously uninitialized object from some other object's data.
An assignment operator is used to replace the data of a previously initialized object with some other object's data.
Doing obj_1 = obj
, if my obj_1 was previously initialized results in calling the copy constructor
instead of operator=
function inside my class A
as I was expecting?
Also, inside vector
there is already an operator=
function. How can I know when will be called each?
vector<A> obj {1,2,3};
vector<A> obj_1;
obj_1 = obj; // Why copy constructor called instead of function operator= inside my class
Is there any way a
vector
can be declared and instantiated while skipping the copying operation?
No. When you do vector<A> obj {1,2,3}
the compiler creates a std::initializer_list<A>
from the values provided. That std::initializer_list
creation is the reason you see the three normal constructor calls. The vector then has to copy those elements because the underlying storage for those elements is const
. There is no was to get around that with list initialization. Even vector<A> obj {A(1),A(2),A(3)}
would still cause copies.
If you don't want that then one thing you can do is create storage for the elements using reserve
, and then use emplace_back
to directly construct the objects in the vector like
vector<A> obj;
obj.reserve(3);
for (int i = 1; i < 4, ++i)
obj.emplace_back(i);
Doing
obj_1 = obj
, if myobj_1
was previously initialized results in calling the copy constructor instead ofoperator=
function inside my class A as I was expecting?
This is because obj_1
is empty. Since it is empty, there is no element to call the assignment operator on. Instead what it does is create elements in obj_1
that are copies of obj
and the most efficient way to do that is to just call the copy constructor instead of default constructing the objects and then assigning to them.
If you had
vector<A> obj {1,2,3};
vector<A> obj_1 {3, 4, 5};
obj_1 = obj;
Instead then you would see the assignment operator be used instead since there are objects to actually assign to.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.