12월 13, 2016

[EC++ 14] Think carefully about copying behavior in resource-managing classes.


Synopsis

mutex를 사용하는 경우,  lock(..)  unlock(..) 을 매 번 잊지 말아야 한다. 이를 해결하기 위해 RAII(Resource Acquisition Is Initialization) class의 사용을 고려해 볼 수 있다.



RAII object의 copy behavior 정의

  • Prohibit copy
  • RAII 객체의 copy operation을 허용하지 않아야 하는 경우가 많이 있다. 예를 들어 underlying resource가  std::mutex 인 경우 copy operation은 의미가 없을 뿐 아니라, 잘못된 동작을 초래할 것이다.

  • Reference-count the underlying resource
  • 동일한 객체가 여러번 사용되는 경우, 마지막 사용이 끝난 시점에서 resource가 release 되어야 한다. 이런 경우 적합한 방식이 reference-counting 방식으로,  std::shared_ptr 와 같은 구현 예가 있다.

    만약 자신의 RAII class에 reference counting 방식을 도입하고 싶다면 referece counting을 직접 구현하지 않고,  std::shared_ptr 을 멤버 필드로 정의하여 같은 효과를 볼 수 있다. Synopsis의 Lock class를 이러한 방식으로 구현할 수 있는데, 이 경우 RAII class의 Reference-count가 0이 되어도 mutex가 destruct되어선 안된다. 이 구현은  std::shared_ptr 의 deleter를 지정하여 해결할 수 있다.

  • Copy the underlying resource
  • Resource-managing class를 사용하는 이유가 오직, heap 메모리의 자동 해제 뿐인 경우, 동일한 resource의 카피를 여러 개 보유할 수도 있다. 이런 경우 resource-managing class의 copy operation은 해당 객체의 underlying resource를 deep-copy 해야 한다.

  • Transfer ownership of the underlying resource
  • copy behavior가 해당 객체의 underlying resource의 ownership을 이양하는 경우를 생각해 볼 수 있다. 이러한 구현의 예로  std::unique_ptr 가 있다.



Summary

  • Copying an RAII object entails copying the resource it manages, so the copying behavior of the resource determines the copying behavior of the RAII object.
  • Common RAII class copying behaviors are disallowing copying and performing reference counting, but other behaviors are possible.

Reference

  • Effective C++ by Scott Meyers

댓글 없음:

댓글 쓰기