09.27

신승빈·2022년 9월 27일
0

KGCA 수업

목록 보기
45/128

Smart Pointer

고전적 포인터 방식의 문제점

기존의 new 할당 방식은 매번 delete를 수행해야 하며, 예기치못한 이중 delete의 문제가 발생할 수 있고, 또한 delete하더라도 pointer 변수의 위치를 바꾸지 않으면 이미 삭제된 지역을 가리키는 문제가 발생할 수 있음

PTR* ptr = new PTR;
delete ptr;
// ...
ptr->func();
// ...
delete ptr;

만약 Factory Pattern같이 생성이 위임된 구조로 메모리를 할당한다면 메모리 해제의 책임 주체가 애매해질 수 있음

특징

Smart Pointer는 결국 Smart Pointer형 Template 변수
Pointer를 내부에 보관하는 것일뿐 stack 객체로 생성한다면 delete할 수 없으며, pointer객체로 생성한다면 Smart Pointer type pointer일 뿐이다.

std::shared_ptr<>

std::shared_ptr<ClassType> variable(new ClassType); // 추천하지는 않음
std::shared_ptr<ClassType> variable = std::make_shared<ClassType> // 추천하는 생성 방식

생존주기가 끝(ref_count == 0)날 경우 자동으로 소멸자 수행
get()을 통해 pointer에 직접 접근 가능
shared_ptr에 주소값으로 직접 매개변수를 넣어줄 경우, ref_count가 정상적으로 작동하지 않음

ClassType* ptr = new ClassType;
std::shared_ptr<ClassType> var1(ptr);	// ref_count = 1
std::shared_ptr<ClassType> var2(ptr);	// ref_count = 1

std::shared_ptr은 복사가 발생하면 ref_count가 증가됨

점검사항
void func(std::shared_ptr<ClassType>* sPtr);

위의 경우 sPtr의 ref_count에 변화가 있는가?

점검사항

std::shared_ptr은 multi thread에 안전한가?

Reference : http://rette.iruis.net/2016/10/shared_ptr-%EA%B0%9D%EC%B2%B4%EB%A5%BC-%EB%A9%80%ED%8B%B0%EC%8A%A4%EB%A0%88%EB%93%9C%EC%97%90%EC%84%9C-%EC%82%AC%EC%9A%A9%ED%95%A0-%EB%95%8C/
Reference : https://stackoverflow.com/questions/14482830/stdshared-ptr-thread-safety
점검사항
std::shared_ptr<ClassType> var = std::make_shared<ClassType>;
var = nullptr;

std::shared_ptr<ClassType> nullptrSM = nullptr;
var = nullptrSM;
var.swap(nullptrSM);
var.reset();

shared_ptr의 내부에 들어있는 포인터를 변경 시 소멸자 수행
Smart Pointer의 수동 삭제 가능
swap()함수는 실제로 삭제를 수행하는가?

std::unique_ptr<>

std::unique_ptr<ClassType> variable(new ClassType);
std::unique_ptr<ClassType> variable = std::make_unique<ClassType>;

LValue copy construct 불가능
RValue move construct 가능

std::unique_ptr<ClassType> origin = std::make_unique<ClassType>;
std::unique_ptr<ClassType> lValue = origin;				// 불가능
std::unique_ptr<ClassType> rValue = std::move(origin);	// 가능, 소유권 이전

Pointer parameter, Reference parameter방식은 가능하지만 Unique Pointer의 소유권 개념에 맞지 않는 사용법
get()을 이용해 pointer 원본을 넘겨줄 수는 있지만 delete의 위험이 존재

결론

외부로 넘겨줄 일이 없는 변수는 unique_ptr를 쓰는것이 좋을 듯
외부로 넘겨줄 일이 있는 변수(Manager class의 element)는 shared_ptr를 쓰는것이 좋을 듯

Reference : https://modoocode.com/252

ComPtr

DirectX에서 사용하는 COM객체를 쉽게 관리하기 위한 Smart Pointer 종류
Release()를 자동으로 수행

#include <wrl.h>

Microsoft::WRL::ComPtr<ClassType>

DirectX에서 생성시 요구하는 이중 포인터(void**)를 위한 GetAddressOf()함수 존재
&var 보다 GetAddressOf()를 통해 접근하는 것을 추천
template class이므로 꼭 IUnknown만을 매개변수로 전달할 필요는 없을 듯

profile
이상을 길잡이 삼아 로망을 추구합니다.

0개의 댓글