1편, 2편, 3편에서 이어집니다.

문법 정리

스마트 포인터

스마트 포인터란 자신이 소멸될 때 소멸자에서 자신이 가지고 있는 객체의 자원도 해제해주는 포인터 Wrapper 클래스라고 볼 수 있다.

unique_ptr, shared_ptr, weak_ptr이 존재하며 c++11에 등장한다.

unique_ptr

특정 객체에 유일한 소유권을 부여하는 객체를 unique_ptr이라고 한다.

이는 double free 에러를 방지한다.

std::unique_ptr<A> 처럼 사용할 수 있다.

auto a = make_unique<A>(5);

shared_ptr

다른 shared_ptr과 동일한 객체를 공유할 수 있는 포인터이다.

image.png

use_count로 현재 참조 개수를 알 수 있다.

void solve() {  
   auto a = make_shared<A>(5);  
   {  
      shared_ptr<A> b = a;  
  
      cout << a.use_count(); // 2  
   }  
   cout << a.use_count(); // 1  
}

이러한 shared_ptr들의 참조에 대한 메타데이터들은 처음으로 만들어지는 shared_ptr가 control block을 만들어 그것에 대해 모두 참조를 하는 방식으로 데이터를 공유한다.

image.png

std::make_shared로 생성하는 것이 동적 할당이 쓸데없이 더 되는 것을 방지할 수 있다.

std::make_uniquestd::make_shared는 객체 자체를 받지않고 객체의 생성자의 인자를 그대로 Perfect forwarding(by Move Semantics)하는 방식으로 받는데, 이는 동적 할당을 방지하고 성능 최적화가 되게 한다.

shared_ptr사용시 주의점

Control block이 중복되어서 만들어지지 않게 유의해야 한다.

shared_ptr에 주소값을 받는 생성자를 전달한다면 Control Block이 한 객체에 대해 여러개가 만들어져서 double free는 따놓은 당상이다.

따라서 웬만하면 대입 연산자와 make_shared만을 사용해서 만드는것이 바람직하다.

weak_ptr

shared_ptr을 약하게 참조하는 스마트 포인터이다. unique_ptr은 참조할 수 없다.

이는 순환참조 방지용 스마트 포인터이고 weak_ptrweak_ptrshared_ptr의 대입연산자나 함수의 인자로 받는것이 정형적이다.

weak_ptr은 객체에 접근할 수 없고 lock으로 먼저 shared_ptr 객체를 얻어온 후에 접근할 수 있다.

단, shared_ptr로 참조하고 있던 객체가 소멸되지 않은 상태에서만 객체를 담은 shared_ptr객체가 나오며 그렇지 않으면 사용하면 안된다.

이는 다음과 같은 코드로 사용될 수 있다.

void solve() {  
   std::weak_ptr<int> weak;  
   {  
      auto ptr = std::make_shared<int>(10);  
      weak = ptr;  
   }  
  
   if (std::shared_ptr<int> v = weak.lock()) {  
      cout << *v;  
   } else {  
      cout << "no";  
   }  
}

no가 호출되는 것을 볼 수 있다.

c++ Castings

  • static_cast: 컴파일 타임에 타입 변환을 하고 C에서 대괄호 캐스팅과 비슷하지만 좀 더 강력한 컴파일 에러를 지원한다.
  • dynamic_cast : 런타임에 캐스팅을 검사하고 보통 다운캐스팅에 쓰인다.
    • 캐스팅에 실패한다면 포인터라면 nullptr을 반환한다.
  • const_cast: const를 타입에서 제거한다.
  • reinterpret_cast 가장 위험하고 강력한 캐스팅으로, 전혀 상관없는 타입도 변환할 수 있지만 사용에 주의를 요한다.

Smart Pointer Castings

  • static_pointer_cast: static_cast의 스마트 포인터 버전
  • dynamic_pointer_cast: dynamic_cast의 스마트 포인터 버전
  • const_pointer_cast: const_cast의 스마트 포인터 버전

Categories:

Updated:

Comments