Let's consider that I have defined some classes B
and C
.
Now, let's consider the following class:
class A{
public:
int att1;
int att2;
std::shared_ptr<B> b_ptr;
std::shared_ptr<C> c_ptr;
A(const A& a);
};
Now, the question is about how to implement the copy constructor.
Currently in the code, this is what is being done:
A::A(const A& a){
att1 = a.att1;
att2 = a.att2;
b_ptr = a.b_ptr;
c_ptr = a.c_ptr;
}
The last two lines will call the copy constructor of std::shared_ptr
and increment the number of owners of the underlying pointer by 1.
But, isn't it a bad idea to have a copy constructor do that? It means that anywhere the copy constructor is called, it will actually have a relation with the initial object because the objects of class B
and C
aren't actually copied, but only the pointers are.
I realize that thanks to the use of shared_ptr
, at least this will not be making any memory leaks.
Is it a common practice to do that? Is there any legitimate reason to do it? Or should I just avoid it all together?
CodePudding user response:
Let's imagine class A is class Person and class B is class car.
Is it OK that a copy of class Person points to the same original car? Yes
--- So just copying a pointer is OK.
Is it OK that when the last copy of Person is destroyed the car gets destroyed? Yes
--- So just copying smart pointers is OK.
Is it OK that a copy of class Person will get its own copy of a car? Yes
--- So copying the whole pointed to object is also OK.
All of those semantics can be valid. It is up to you to chose which one is appropriate for your logic.
CodePudding user response:
The last two lines will call the copy constructor of
std::shared_ptr
and increment the number of owners of the underlying pointer by 1.
Actually, they call the copy assignment operator, not the copy constructor.
But, isn't it a bad idea to have a copy constructor do that?
No, because shared_ptr
is meant to be copied like this. Sharing ownership of a pointer across multiple instances is its sole purpose.
It means that anywhere the copy constructor is called, it will actually have a relation with the initial object because the objects of class
B
andC
aren't actually copied, but only the pointers are.
Exactly, yes. That is what shared_ptr
is specifically designed for.
Is it a common practice to do that?
In this case, yes. But if raw pointers had been used instead, then no.