C++/Google C++ Style Guide

Google-Specific Magic

ukjin 2025. 5. 26. 22:54
반응형

C++ code를 더 강력하도록 만드는 tricks와 utilitis가 있고,  C++를 사용하는 다양한 방식은 다른 곳에서 보는 것과는 다를 수도 있다.

Ownership and Smart Pointer

동적으로 할당된 objects를 위해 single, fixed owner를 가지는 것을 선호하자. smart pointers로 ownership을 전달하는 것을 선호하자.

Definition:

"Ownership"은 동적으로 할당된 메모리 (그리고 다른 리소스)를 관리하기 위한 bookkeeping technique 이다. 동적으로 할당된 object의 owner는 더이상 필요하지 않을 때 삭제되는 것을 보장하는 책임을 가진 object 또는 function이다. Ownership은 가끔 공유될 수 있는데, 마지막 owner가 일반적으로 삭제하는 책임을 가진다. 심지어 ownership이 공유되지 않을 경우 한곳에서 다른 곳으로 옮겨질 수 있다.

"Smart" pointers는 pointer처럼 행동하는 ㅊlass이다, e.g, *와 -> 연산자를 overloading 함으로써. 몇몇 smart pointer types는 ownership bookkeeping을 자동화하는데 사용될 수 있고 이러한 책임을 충족하는 것을 보장한다. std::unique_ptr은 동적으로 할당된 object의 독점적인 ownership을 표현하는 smart pointer type이다; std::unique_ptr이 scope 밖으로 갈 때 object는 삭제된다. 이것은 복사될 수 없지만 ownership을 이동하는 것을 표현하는 move는 가능하다. std::shared_ptr은 동적으로 할당된 object의 공유된 ownership을 표현하는 smart poniter type이다. std::shared_ptr은 복사될 수 있다; object의 ownership은 모든 복사본 간 공유되며, 마지막 std::shared_ptr이 파괴될 때 object는 삭제된다.

Pros: 

  • 일련의 ownership logic 없이는 동적으로 할당된 메모리를 관리하는 것은 사실상 불가능하다.
  • object의 ownership을 전달하는 것은 복사하는 것보다 더 쌀 수 있다(만약 복사가 가능한 경우)
  • ownership을 전달하는 것은 pointer 또는 reference를 'borrowing'보다 더 단순할 수 있는데, 두 user 간의 object의 lifetime을 조정할 필요성을 줄이기 때문이다.
  • Smart pointer는 ownership logic을 명시적이고 self-documenting, unambiguous로 만들어서 가독성을 향상시킨다.
  • Smart pointer는 manual ownership bookkeeping 를 제거할 수 있고 code를 단순화하며 큰 오류 클래스를 배제할 수 있다.
  • const object의 경우, 공유된 ownership은 deep copying의 단순하고 효율적인 대안이 될 수 있다.

Cons:

  • Ownership은 pointer를 통해 표현되고 전달되어야만 한다(smart or plain인지 아닌지). Pointer semantics는 value semantic보다 더 복잡하며 특히 APIs에서는: 다른 이슈 간의 ownership 뿐 아니라 aliasing, lifetime, mutability에 관해 걱정해야만한다.
  • value semanctics의 성능 비용은 주로 과대평가되며, ownership의 성능 이점은 가독성과 복잡성 비용을 정당화하지 못한다.
  • ownership을 전달하는 APIs는 clients를 single memory management model로 강제한다.
  • smart pointer를 사용하는 코드는 resource release 위치에 관해 덜 명시적이다.
  • std::unique_ptr은 move semantics를 사용하여 ownership 이동을 표현하는데, 상대적으로 새롭고 몇몇 프로그래머에게는 혼란스럽다.
  • 공유되는 ownership은 신중한 ownership 설계에서 유혹적인 대안이 될 수 있으며 시스템의 설계를 혼란스럽게 한다.
  • 공유된 ownership은 run-time에서 명시적인 bookkepping을 필요로 하며 이는 비용이 될 수 있다.
  • 몇몇 경우에서 (e.g., cyclic references) 공유된 ownership을 가진 objects는 삭제되지 않을 수 있다.
  • Smart pointer는 plain pointer의 완벽한 대체제가 아니다.

Decision:

만약 동적 할당이 필요하다면, 할당하는 코드와 함께 ownership을 유지하는 것을 선호하자. 만약 다른 코드에서 object로 접근을 필요로 할 경우, ownership을 전달하지 않고 pointer 또는 reference를 전달하거나 copy를 전달하는 것을 고려하자.  std::unique_ptr 를 사용하여 명시적으로 ownership 전달을 선호하자. 예를 들어:

std::unique_ptr<Foo> FooFactory();
void FooConsumer(std::unique_ptr<Foo> ptr);

매우 좋은 이유 없이 공유된 ownership을 code에 사용하는 설계는 피하자. 이러한 좋은 이유 중 하나는 비싼 복사 비용을 피하기 위해서지만, 만약 성능 이점이 막대할 경우와 immutable (i.e., std::shared_ptr<const Foo>)일 경우에만 사용하자. 만약 공유된 ownership을 사용한다면, std::shared_ptr 사용을 선호하자.

std::auto_ptr를 절대 사용하지 말자. 대신, std::unique_ptr을 사용하자.

cpplint

style error를 감지하기 위해 cpplint.py를 사용하자.

cpplint.py는 source file을 읽고 많은 style error를 감지하는 tool이다. 완벽하진 않지만 fals positives 와 fals negatives를 가지며, 여전히 가치있는 tool이다.

몇 프로젝트에서 프로젝트 tool에서 cpplint.py를 실행하는 법을 소개한다. 만약 기여하는 프로젝트에서 cpplint.py를 사용하지 않는다면, 별도로 다운로드 하자.

 

반응형

'C++ > Google C++ Style Guide' 카테고리의 다른 글

Naming  (1) 2025.06.19
Other C++ Features  (0) 2025.05.26
Functions  (1) 2025.05.25
Classes  (0) 2025.05.20
Scoping  (0) 2025.05.15