이글은 "전문가를 위한 c++(개정4판)"을 학습한 내용을 직접 실습해보며 정리한 Review용 글입니다.
스마트 포인터
스마트 포인터는 delete나 delete[]를 사용할 필요가 없이 자동으로 메모리를 해제 시킵니다. c++에서 가장 중요한 스마트 포인터 타입은 다음 두 가지입니다.
#include<memory>
std::unique_ptr
std::shared_ptr
unique_ptr은 가리키는 객체를 일반 포인터로 가리킬 수 없을 뿐만 아니라 동일 타입의 unique_ptr로도 가리킬 수 없습니다. 이는 복사생성자와 대입연산자가 구현이 되어 있지 않기 때문입니다.
unique_ptr의 생성할 때는 두 가지 방법이 있습니다.
#include <iostream>
#include <memory> //스마트 포인터 사용을 위해
using namespace std;
int main()
{
//unique_ptr 생성하는 첫번째 방법
unique_ptr<int> uniquePointer1(new int);
*uniquePointer1 = 10;
cout << "첫번째 방법으로 생성한 값 : " << *uniquePointer1 << endl;
//unique_ptr 생성하는 두번째 방법
auto uniquePointer2 = make_unique<int>();
*uniquePointer2 = 10;
cout << "두번째 방법으로 생성한 값 : " << *uniquePointer2 << endl;
return 0;
}
결과
첫번째 방법으로 생성한 값 : 10
두번째 방법으로 생성한 값 : 10
첫번째 방법은 c++14 이전에 사용해 왔던 방식입니다. 타입을 두번 적어야하는 불편함이 있습니다. 두번째 방법은 c++14 이후에 추가된 방법입니다. 스마트 포인터의 사용법은 일반 포인터의 사용법과 같습니다. 위 예시에서 사용한 역참조 방식도 일반 포인터 역참조 방식과 동일하며 클래스나 구조체일 경우 ->연산자로 멤버에 접근할 수 있습니다.
unique_ptr는 배열을 생성할 수 있습니다. 배열을 생성하는 방법은 다음과 같습니다.
long arraySize = 1000;
auto myArrayBuffer = make_unique<int[]>(arraySize);
또 다른 방법은 c++17이후에 나온 방법입니다. 다음 예제 처럼 int 에 배열 연산자 []를 붙여서 int[]로 선언하는 방법입니다.
long arraySize = 1000;
unique_ptr<int[]> myArrayBuffer(new int[arraySize]);
shared_ptr도 사용법은 unique_ptr과 유사합니다. 차이점은 복사생성자와 대입연산자가 정의되어 있어서 데이터를 공유할 수 있습니다. 그리고 shared_ptr에 대한 대입연산이 발생할 때 마다 레퍼런스 카운트가 하나씩 증가합니다. 레퍼런스 카운트는 shared_ptr이 가리키는 횟수를 의미합니다.즉 횟수만큼 데이터를 소유하고 있다는 뜻입니다. shared_ptr이 스코프를 벗어나면 레퍼런스 카운트가 감소합니다. 그러다가 카운트가 0이되면 그때 객체를 해제합니다.
포인터 생성방법도 unique_ptr 처럼 두가지 방식으로 생성합니다.
#include <iostream>
#include <memory>
using namespace std;
int main()
{
shared_ptr<int> sharedPointer1(new int);
*sharedPointer1 = 10;
cout << "첫번째 방법으로 생성한 값 : " << *sharedPointer1 << endl;
auto sharedPointer2 = make_shared<int>();
*sharedPointer2 = 20;
cout << "두번째 방법으로 생성한 값 : " << *sharedPointer2 << endl;
return 0;
}
결과
첫번째 방법으로 생성한 값 : 10
두번째 방법으로 생성한 값 : 20
shared_ptr도 배열을 생성할 수 있습니다. 하지만 unique_ptr와는 다르게 make_shared()로는 생성할 수 없습니다.
unique_ptr에서 배열을 생성했던 c++17 이후에 나온 두번째 방식으로 가능합니다.
long arraySize = 1000;
shared_ptr<int[]> myArrayBuffer(new int[arraySize]);
다음은 위 방식으로 작성한 예제입니다.
#include <iostream>
#include <memory>
using namespace std;
int main()
{
long arraySize = 1000;
shared_ptr<int[]> myArrayBuffer(new int[arraySize]);
for(int i = 0; i < arraySize; i++) {
myArrayBuffer[i] = i; // 배열에 값 대입
}
//일부 배열 값을 출력한다.
for(int i = 20; i < 30; i++) {
cout << "index" << i << " : " << myArrayBuffer[i] << endl;
}
return 0;
}
결과
index20 : 20
index21 : 21
index22 : 22
index23 : 23
index24 : 24
index25 : 25
index26 : 26
index27 : 27
index28 : 28
index29 : 29
'Program Language > c++' 카테고리의 다른 글
c++ 기초(레퍼런스) (1) | 2023.01.17 |
---|---|
c++ 기초 (const 키워드의 사용법) (4) | 2023.01.16 |
c++ 기초(동적 배열 할당) (0) | 2023.01.13 |
c++ 기초(포인터 사용법) (0) | 2023.01.12 |
c++ 기초(스택과 힙) (0) | 2023.01.11 |
댓글