일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 이진트리
- Raycast
- ML-Agents
- 유니티 리소스매니저
- 깊이 우선 탐색
- 유니티 머신러닝
- 유니티 시야 가림
- InputManager
- 너비 우선 탐색
- 오브젝트 풀링
- 유니티 Collision
- LookRotation
- LayerMask
- Mathf.Clamp
- eulerAngles
- 유니티 Rotate
- 유니티 ResourceManager
- 소스코드 줄번호
- 알고스팟
- 유니티 오브젝트 풀링
- c++
- unity
- 코드블럭 테마
- LFS
- 유니티 InputManager
- 유니티 Vector3
- git-lfs
- c++ 문자열 자르기
- Quaternion.Euler
- 유니티
- Today
- Total
무민은귀여워
스마트 포인터 ( unique_ptr, shared_ptr, weak_ptr ) 본문
스마트 포인터(smart pointer)
스마트 포인터(smart pointer)란 포인터처럼 동작하는 클래스 템플릿으로, 사용이 끝난 메모리를 자동으로 해제해 준다.
1. unique_ptr
하나의 스마트 포인터만이 특정 객체를 소유할 수 있도록, 객체에 소유권 개념을 도입한 스마트 포인터입니다.
이 스마트 포인터는 해당 객체의 소유권을 가지고 있을 때만, 소멸자가 해당 객체를 삭제할 수 있다.
unique_ptr 인스턴스는 move() 멤버 함수를 통해 소유권을 이전할 수는 있지만, 복사할 수는 없다.
소유권이 이전되면, 이전 unique_ptr 인스턴스는 더는 해당 객체를 소유하지 않게 재설정된다.
※ 보통의 C++ 객체에 대해 스마트 포인터가 필요한 상황에서는 주로 unique_ptr을 사용하면 된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
// 1. ======================================================================================
unique_ptr<int> ptr01(new int(5)); // int형 unique_ptr인 ptr01을 선언하고 초기화함.
auto ptr02 = move(ptr01); // ptr01에서 ptr02로 소유권을 이전함.
// unique_ptr<int> ptr03 = ptr01; // 대입 연산자를 이용한 복사는 오류를 발생시킴.
ptr02.reset(); // ptr02가 가리키고 있는 메모리 영역을 삭제함.
ptr01.reset(); // ptr01가 가리키고 있는 메모리 영역을 삭제함.
// 2. ======================================================================================
int main(void)
{
unique_ptr<Person> hong = make_unique<Person>("길동", 29);
hong->ShowPersonInfo(); // 출력. 길동의 나이는 29살입니다.
return 0;
}
void Person::ShowPersonInfo() { cout << name_ << "의 나이는 " << age_ << "살입니다." << endl; }
|
cs |
2. shared_ptr
shared_ptr은 하나의 특정 객체를 참조하는 스마트 포인터가 총 몇 개인지를 참조하는 스마트 포인터이다.
이렇게 참조하고 있는 스마트 포인터의 개수를 참조 횟수(reference count)라고 한다.
참조 횟수는 특정 객체에 새로운 shared_ptr이 추가될 때마다 1씩 증가하며, 수명이 다할 때마다 1씩 감소한다.
따라서 마지막 shared_ptr의 수명이 다하여, 참조 횟수가 0이 되면 delete 키워드를 사용하여 메모리를 자동으로 해제한다.
※ make_shared() 함수를 사용하면 shared_ptr 인스턴스를 안전하게 생성할 수 있다.
make_shared() 함수는 전달받은 인수를 사용해 지정된 타입의 객체를 생성하고, 생성된 객체를 가리키는 shared_ptr을 반환한다.
1
2
3
4
5
6
7
8
9
10
11
|
shared_ptr<int> ptr01(new int(5)); // int형 shared_ptr인 ptr01을 선언하고 초기화함.
cout << ptr01.use_count() << endl; // 1
auto ptr02(ptr01); // 복사 생성자를 이용한 초기화
cout << ptr01.use_count() << endl; // 2
auto ptr03 = ptr01; // 대입을 통한 초기화
cout << ptr01.use_count() << endl; // 3
|
cs |
3. weak_ptr
weak_ptr은 하나 이상의 shared_ptr 인스턴스가 소유하는 객체에 대한 접근을 제공하지만, 소유자의 수에는 포함되지 않는 스마트 포인터이다.
shared_ptr은 참조 횟수(reference count)를 기반으로 동작하는 스마트 포인터이므로,
만약 서로가 상대방을 가리키는 shared_ptr를 가지고 있다면, 참조 횟수는 절대 0이 되지 않아 메모리는 영원히 해제되지 않는다.
이렇게 서로가 상대방을 참조하고 있는 상황을 순환 참조(circular reference)라고 한다.
weak_ptr은 바로 이러한 shared_ptr 인스턴스 사이의 순환 참조를 제거하기 위해서 사용된다.
4. 스마트 포인터 선택
어떤 스마트 포인터를 사용해야 할까?
만일 프로그램이 하나의 객체에 대해 하나 이상의 포인터를 사용한다면, shared_ptr을 선택해야한다.
복사나 대입 연산을 포함하고 있는 많은 STL 알고리즘들은 shared_ptr로 동작해야 한다.
프로그램이 같은 객체를 가리키기 위해 다중 포인터를 필요로 하지 않는다면, unique_ptr을 사용해야 한다.
new로 대입된 메모리를 리턴하는 함수의 리턴 타입에는 가장 적절한 선택이다.
하나의 unique_ptr에서 다른 unique_ptr에 대입할 수 있는 상황과 동일한 상황이라면 unique_ptr을 shared_ptr에 대입할 수 있다. 원본이 rvalue이어야 한다.
[c++ 기초 플러스 6판 - p1239 참고]
※ 참고 사이트
http://tcpschool.com/cpp/cpp_template_smartPointer
https://api.unrealengine.com/KOR/Programming/UnrealArchitecture/SmartPointerLibrary/index.html
'IT > c, c++' 카테고리의 다른 글
문자열 자르기 substr / istringstream / stringstream / strtok (0) | 2022.05.20 |
---|---|
csv 파일 읽고 쓰기 (0) | 2021.05.18 |
같은 자료형인 두 값을 교환하는 함수 형식 매크로 ( swap 매크로 ) (0) | 2021.05.18 |
typedef 보다 별칭 선언을 선호하라 (0) | 2020.01.17 |
[c++] map 사용 예제 (0) | 2019.11.28 |