I was reading Effective C++ by Scott meyers and author was comparing pass by value and pass by reference. For user defined type it is recommended to use pass by reference and for built in type pass by value. I am looking for an example that explains the following paragraph that states pass by value can be costly even for small user defined object.
Built-in types are small, so some people conclude that all small types are good candidates for pass-by-value, even if they’re user-defined. This is shaky reasoning. Just because an object is small doesn’t mean that calling its copy constructor is inexpensive. Many objects — most STL containers among them — contain little more than a pointer, but copying such objects entails copying everything they point to. That can be very expensive.
It depends on whether your copy is deep copy or just shallow copy.(Or value-like class/pointer-like class).For example,A is a class with just one pointer to another object:
struct B;
struct A
{
B* pB;
~A{delete pB;}
}a1,a2;
if you copy A
by value,like a1=a2
,the default bitwise copy assignment will be called, which is of little cost,however,by doing this you will let the pB
in a1
,a2
points to the same heap memory.That is to say,the dtor ~A()
may be called twice,which is undefined behavior.
So we have to do like this:
struct A
{
B* pB;
const A& operator=(const A&rhs)
{
if(this!=&rhs)
{
delete pB;
pB=new pB;
*pB=*rhs.pB;
}
return *this;
}
//the copy/move constructor/assignment should also be redefined
~A{delete pB;}
}a1,a2
The code snippet above will call the copy assignment of B
,which maybe very costly.
To sum up,if your class is trivially copyable,then copying a small user-defined class,or passing by value, does not cost much,else it depends.
If you still want to pass by value and do not want to trigger undefined behavior,shared_ptr may be a good choice for you.But as pointed out by @Arne Vogel ,the implementation of shared_ptr is thread-safe,which requires atomic operation on reference counting that will increase the cost.