๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ“ Development Study/๐Ÿ‘จ๐Ÿพ‍๐Ÿ’ป C++

์Šค๋งˆํŠธ ํฌ์ธํ„ฐ

by eazuooz 2023. 1. 3.

C++ ํ”„๋กœ๊ทธ๋žจ์—์„œ new ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋™์ ์œผ๋กœ ํ• ๋‹น ๋ฐ›์€ ๋ฉ”๋ชจ๋ฆฌ๋Š”, ๋ฐ˜๋“œ์‹œ delete ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด์ œ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. C++์—์„œ๋Š” ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ (memory leak)์œผ๋กœ๋ถ€ํ„ฐ ํ”„๋กœ๊ทธ๋žจ์˜ ์•ˆ์ •์„ฑ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ(smart pointer)๋ž€ ํฌ์ธํ„ฐ์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๋Š” ํด๋ž˜์Šค ํ…œํ”Œ๋ฆฟ์œผ๋กœ, ์‚ฌ์šฉ์ด ๋๋‚œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ž๋™์œผ๋กœ ํ•ด์ œํ•ด ์ค๋‹ˆ๋‹ค.

 

์Šค๋งˆํŠธ ํฌ์ธํ„ฐ์˜ ๋™์ž‘

๋ณดํ†ต new ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ๊ธฐ๋ณธ ํฌ์ธํ„ฐ๊ฐ€ ์‹ค์ œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ์ดˆ๊ธฐํ™”ํ•œ ํ›„์—, ๊ธฐ๋ณธ ํฌ์ธํ„ฐ๋ฅผ ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ์— ๋Œ€์ž…ํ•˜์—ฌ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ์ •์˜๋œ ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ์˜ ์ˆ˜๋ช…์ด ๋‹คํ•˜๋ฉด ์†Œ๋ฉธ์ž๋Š”, deleteํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ• ๋‹น๋œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ž๋™์œผ๋กœ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ new ํ‚ค์›Œ๋“œ๊ฐ€ ๋ฐ˜ํ™˜๋˜๋Š” ์ฃผ์†Œ๊ฐ’์„ ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ์— ๋Œ€์ž…ํ•˜๋ฉด, ๋”ฐ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œํ•  ํ•„์š”๊ฐ€ ์—†์–ด์ง‘๋‹ˆ๋‹ค.

 

์Šค๋งˆํŠธ ํฌ์ธํ„ฐ์˜ ์ข…๋ฅ˜

1. unique_ptr

2. shared_ptr

3. weak_ptr

 

 

unique_ptr

unique_ptr์€ ํ•˜๋‚˜์˜ ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ๋งŒ์ด ํŠน์ • ๊ฐ์ฒด๋ฅผ ์†Œ์œ ํ• ์ˆ˜ ์žˆ๋„๋ก, ๊ฐ์ฒด์— ์†Œ์œ ๊ถŒ ๊ฐœ๋…์„ ๋„์ž…ํ•œ ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ ์ž…๋‹ˆ๋‹ค.

 

์ด ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ๋Š” ํ•ด๋‹น ๊ฐ์ฒด์˜ ์†Œ์œ ๊ถŒ์„ ๊ฐ€์ง€๊ณ  ์žˆ์„ ๋•Œ๋งŒ, ์†Œ๋ฉธ์ž๊ฐ€ ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ์‚ญ์ œํ• ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

unique_ptr ์ธ์Šคํ„ด์Šค๋Š” move() ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์†Œ์œ ๊ถŒ์„ ์ด์ „ํ•  ์ˆ˜๋Š” ์žˆ์ง€๋งŒ, ๋ณต์‚ฌ ํ•  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค.

์†Œ์œ ๊ถŒ์ด ์ด์ „๋˜๋ฉด, ์ด์ „ unique_ptr ์ธ์Šคํ„ด์Šค๋Š” ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ์†Œ์œ ํ•˜์ง€ ์•Š๊ฒŒ ์žฌ์„ค์ • ๋ฉ๋‹ˆ๋‹ค.

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๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ๋Š” ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์„ ์‚ญ์ œํ•จ.

 

c++ 14์ดํ›„ ๋ถ€ํ„ฐ ์ œ๊ณต๋˜๋Š” make_unique()ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉ ํ•˜๋ฉด unique_ptr์ธ์Šคํ„ด์Šค๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

make_unique()ํ•จ์ˆ˜๋Š” ์ „๋‹ฌ๋ฐ›์€ ์ธ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ์ง€์ •๋œ ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ์ƒ์„ฑ๋œ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” unique_ptr์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. 

.

#include <iostream>

#include <memory>

using namespace std;

 

class Person

{

private:

    string name_;

    int age_;

public:

    Person(const string& name, int age); // ๊ธฐ์ดˆ ํด๋ž˜์Šค ์ƒ์„ฑ์ž์˜ ์„ ์–ธ

    ~Person() { cout << "์†Œ๋ฉธ์ž๊ฐ€ ํ˜ธ์ถœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค." << endl; }

    void ShowPersonInfo();

};

 

int main(void)

{

    unique_ptr<Person> hong = make_unique<Person>("๊ธธ๋™", 29);

    hong->ShowPersonInfo();

    return 0;

}

 

Person::Person(const string& name, int age) // ๊ธฐ์ดˆ ํด๋ž˜์Šค ์ƒ์„ฑ์ž์˜ ์ •์˜

{

    name_ = name;

    age_ = age;

    cout << "์ƒ์„ฑ์ž๊ฐ€ ํ˜ธ์ถœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค." << endl;

}

 

void Person::ShowPersonInfo() { cout << name_ << "์˜ ๋‚˜์ด๋Š” " << age_ << "์‚ด์ž…๋‹ˆ๋‹ค." << endl; }

์œ„์˜ ์˜ˆ์ œ ์—์„œ person ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฅดํ‚ค๋Š” unique_ptr ์ธ์Šคํ„ด์Šค์ธ hong์€ ์ผ๋ฐ˜ ํฌ์ธํ„ฐ์™€ ๋‹ฌ๋ฆฌ ์‚ฌ์šฉ์ด ๋๋‚œ ํ›„์— delete ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

 

shared_ptr

shared_ptr์€ ํ•˜๋‚˜์˜ ํŠน์ • ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๋Š” ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ๊ฐ€ ์ด ๋ช‡๊ฐœ์ธ์ง€๋ฅผ ์ฐธ์กฐํ•˜๋Š” ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ ์ž…๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ์˜ ๊ฐœ์ˆ˜๋ฅผ ์ฐธ์กฐ ํšŸ์ˆ˜(reference count)๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

์ฐธ์กฐ ํšŸ์ˆ˜๋Š” ํŠน์ • ๊ฐ์ฒด์— ์ƒˆ๋กœ์šด  shared_ptr์ด ์ถ”๊ฐ€ ๋ ๋•Œ๋งˆ๋‹ค 1์”ฉ ์ฆ๊ฐ€ํ•˜๋ฉฐ, ์ˆ˜๋ช…์ด ๋‹คํ•  ๋•Œ๋งˆ๋‹ค 1์”ฉ ๊ฐ์†Œํ•ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋งˆ์ง€๋ง‰ shared_ptr์˜ ์ˆ˜๋ช…์ด ๋‹คํ•˜์—ฌ, ์ฐธ์กฐ ํšŸ์ˆ˜๊ฐ€ 0์ด ๋˜๋ฉด delete ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ž๋™์œผ๋กœ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค.

 

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

์œ„์˜ ์˜ˆ์ œ์—์„œ ์‚ฌ์šฉ๋œ use_count() ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋Š” shared_ptr ๊ฐ์ฒด๊ฐ€ ํ˜„์žฌ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ์ฐธ์กฐ ์ค‘์ธ ์†Œ์œ ์ž์˜ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ด ์ค๋‹ˆ๋‹ค.

 

์œ„์™€ ๊ฐ™์€ ๋ฐฉ๋ฒ• ์ด์™ธ์—๋„ make_shared() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด shared_ptr ์ธ์Šคํ„ด์Šค๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

make_shared() ํ•จ์ˆ˜๋Š” ์ „๋‹ฌ๋ฐ›์€ ์ธ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ์ง€์ •๋œ ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ์ƒ์„ฑ๋œ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” shared_ptr์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์ด ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, ์˜ˆ์™ธ ๋ฐœ์ƒ์— ๋Œ€ํ•ด ์•ˆ์ „ํ•˜๊ฒŒ ๋Œ€์ฒ˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋‹ค์Œ ์˜ˆ์ œ๋Š” Person ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” hong์ด๋ผ๋Š” shared_ptr๋ฅผ make_shared() ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์ƒ์„ฑํ•˜๋Š” ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.

 

shared_ptr<Person> hong = make_shared<Person>("๊ธธ๋™", 29);

cout << "ํ˜„์žฌ ์†Œ์œ ์ž ์ˆ˜ : " << hong.use_count() << endl; // 1

auto han = hong;

cout << "ํ˜„์žฌ ์†Œ์œ ์ž ์ˆ˜ : " << hong.use_count() << endl; // 2

han.reset(); // shared_ptr์ธ han์„ ํ•ด์ œํ•จ.

cout << "ํ˜„์žฌ ์†Œ์œ ์ž ์ˆ˜ : " << hong.use_count() << endl; // 1

 

weak_ptr

weak_ptr์€ ํ•˜๋‚˜ ์ด์ƒ์˜ shared_ptr ์ธ์Šคํ„ด์Šค๊ฐ€ ์†Œ์œ ํ•˜๋Š” ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ ‘๊ทผ์„ ์ œ๊ณตํ•˜์ง€๋งŒ, ์†Œ์œ ์ž์˜ ์ˆ˜์—๋Š” ํฌํ•จ๋˜์ง€ ์•Š๋Š” ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ์ž…๋‹ˆ๋‹ค.

 

shared_ptr์€ ์ฐธ์กฐ ํšŸ์ˆ˜(reference count)๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ์ž…๋‹ˆ๋‹ค.

๋งŒ์•ฝ ์„œ๋กœ๊ฐ€ ์ƒ๋Œ€๋ฐฉ์„ ๊ฐ€๋ฆฌํ‚ค๋Š” shared_ptr๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด, ์ฐธ์กฐ ํšŸ์ˆ˜๋Š” ์ ˆ๋Œ€ 0์ด ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๋ฉ”๋ชจ๋ฆฌ๋Š” ์˜์›ํžˆ ํ•ด์ œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ์„œ๋กœ๊ฐ€ ์ƒ๋Œ€๋ฐฉ์„ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ์ƒํ™ฉ์„ ์ˆœํ™˜ ์ฐธ์กฐ(circular reference)๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

weak_ptr์€ ๋ฐ”๋กœ ์ด๋Ÿฌํ•œ shared_ptr ์ธ์Šคํ„ด์Šค ์‚ฌ์ด์˜ ์ˆœํ™˜ ์ฐธ์กฐ๋ฅผ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

'๐Ÿ“ Development Study > ๐Ÿ‘จ๐Ÿพโ€๐Ÿ’ป C++' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

ํŒŒ์ผ ์ž…์ถœ๋ ฅ  (1) 2022.08.22
์ „์ฒ˜๋ฆฌ๊ธฐ #define  (1) 2022.08.22
exception  (0) 2022.08.22
ํ˜•๋ณ€ํ™˜  (0) 2022.08.22
๋‹คํ˜•์„ฑ  (0) 2022.08.22

๋Œ“๊ธ€