# The Copy&Swap Idiom

This topic is 2161 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Is this not how it's done traditionally? Or am I missing something?

'traditional' isn't a technical term, but in this context it would mean 'plainly wrong and rather straw-mannish'. Of course you can get leakage if you do it that way. You're using raw pointers for resource control. That doesn't mean that C&S is the only alternative. Doing it right is another alternative, as I showed in the block after that.

C&S collects the copying behavior and then adopts it in a single transaction. That's the correct pattern, but C&S is not the only way to implement that pattern, and it can be unclear, make the machine do more work than it needs to, and/or trigger side-effects.

Using smart pointers or other RAII implementors allows you to prepare the new state, and then once everything is created successfully you adopt it. That's the 'normal' way of writing exception safe code. C&S is just a trick for doing that by invoking the copy ctor and then adopting it only if construction succeeds.

It does not magically guarantee exception safety.

Your code here is NOT exception safe!

    // copy constructor
Player( const Player& that ) : m_Texture( new Texture(*that.m_Texture) ),
m_Sprite( new Sprite(*that.m_Texture) ),
m_Health( new m_HealthController(*that.m_Health) )

{
}

What if the allocation for m_Health fails? m_Texture and m_Sprite have already been allocated! How will you reach them in order to release them, since the object failed construction?

##### Share on other sites

Your code here is NOT exception safe!

    // copy constructor
Player( const Player& that ) : m_Texture( new Texture(*that.m_Texture) ),
m_Sprite( new Sprite(*that.m_Texture) ),
m_Health( new m_HealthController(*that.m_Health) )

{
}
What if the allocation for m_Health fails? m_Texture and m_Sprite have already been allocated! How will you reach them in order to release them, since the object failed construction?

Code like this shows why RAII works best when there is only one resource per object. If you wrap each of m_Texture, m_Sprite, and m_Health in it own object, then these sorts of problems go away. Alternatively, proper use of smart pointers used together with make_shared and the like resolves the problems too, because of how make_shared works.

Not that it's not possible to write a class that maintains two resources and is exception safe, but that's doing things the hard way, and is a likely spot for bugs introduced when the code is later maintained.

##### Share on other sites

@Khatharr & King Mir - Ah, I see now. Thanks for the pointers!

• ### Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 18
• 13
• 14
• 44
• 63