๐ ํฌ์คํ
๋ด์ฉ
- ์ค๋งํธ ํฌ์ธํฐ์ ๋ํด์ ์์๋ณด๋๋ก ํฉ์๋ค.
๐ ์ค๋งํธ ํฌ์ธํฐ ์ฌ์ฉ์ด์
์ค๋งํธ ํฌ์ธํฐ๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ํฌ์ธํฐ๋ฅผ ๊ด๋ฆฌํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
โ
์ฝ๋
#include <iostream>
class MyClass
{
public :
int a;
};
int main()
{
MyClass* mClass = new MyClass();
return 0;
}
ํฌ๊ฒ ๋ฌธ์ ๊ฐ ๋ ๊ฑด ์์ด๋ณด์ด์ง๋ง ์ด ์ฝ๋์๋ ํฐ ๋ฌธ์ ์ ์ด ์์ต๋๋ค.
๋ฐ๋ก mClass ๊ฐ์ฒด๊ฐ ๋ฉ๋ชจ๋ฆฌ์์ ํด์ ๋์ง ์๋๋ค๋ ์ ์
๋๋ค.
์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ์ํด RAII ๋์์ธ ํจํด์ด ์ฌ์ฉ๋๊ธฐ๋ ํฉ๋๋ค.
๐ RAII ๋์์ธ ํจํด
โ
์ฝ๋
#include <iostream>
template<typename T>
class RAII
{
public:
RAII() { _inst = new T(); }
~RAII() { delete _inst; }
private:
T* _inst;
};
class MyClass
{
public :
MyClass() { std::cout << "์์ฑ์ ํธ์ถ" << std::endl; }
~MyClass() { std::cout << "์๋ฉธ์ ํธ์ถ" << std::endl; }
public :
int a;
};
int main()
{
RAII<MyClass> mClass{};
return 0;
}
โ
์คํ ๊ฒฐ๊ณผ
// ์์ฑ์ ํธ์ถ
// ์๋ฉธ์ ํธ์ถ
์ด๋ฐ์์ผ๋ก ์๋ก์ด RAII ํจํด์ ์ด์ฉํ๋ ํด๋์ค๋ฅผ ๋ง๋ค์ด์ ํฌ์ธํฐ๋ฅผ ๊ด๋ฆฌํด ์ค ์ ์์ต๋๋ค.
๊ทธ๋ผ ์ด์ ๋ถํฐ๋ ์ค๋งํธ ํฌ์ธํฐ์ ๋ํด์ ์์๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
๐ unique_ptr
๋จผ์ unique_ptr์ ๋ํด์ ์์๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
ํด๋น ์ค๋งํธ ํฌ์ธํฐ๋ ๊ณต์ ๋์ง ์๋ ๊ฐ์ฒด ํฌ์ธํฐ๋ง ๊ด๋ฆฌํ๋ฉฐ ๊ณต์ ์์๋ ์์ ์ ์์ ๊ถ์ ํฌ๊ธฐํด์ผํฉ๋๋ค.
๐ ์ฌ์ฉ๋ฒ(unique_ptr)
#include <iostream>
class MyClass
{
public :
MyClass() { std::cout << "์์ฑ์ ํธ์ถ" << std::endl; }
~MyClass() { std::cout << "์๋ฉธ์ ํธ์ถ" << std::endl; }
public :
int a;
};
int main()
{
std::unique_ptr<MyClass> myCalss = std::make_unique<MyClass>();
return 0;
}
๐ ์ฃผ์์ฌํญ(unique_ptr)
โ
์ฝ๋
#include <iostream>
class MyClass
{
public :
MyClass() { std::cout << "์์ฑ์ ํธ์ถ" << std::endl; }
~MyClass() { std::cout << "์๋ฉธ์ ํธ์ถ" << std::endl; }
public :
int a;
};
int main()
{
MyClass* mClass = new MyClass();
std::unique_ptr<MyClass> myCalss { mClass };
std::unique_ptr<MyClass> myCalss2 { mClass };
myCalss2.reset();
return 0;
}
์ด๋ฐ์์ผ๋ก ๊ฐ์ธ ํฌ์ธํฐ๋ฅผ ๋๊ฐ์ unique_ptr๋ก ๊ด๋ฆฌ ์ ํ๋์์ ๊ฐ์ ์ด๊ธฐํ ํ๋ฉด 2๋ฒ์ ์๋ฉธ์๊ฐ ํธ์ถ๋๊ฒ ๋ฉ๋๋ค.
โ
์คํ๊ฒฐ๊ณผ
// ์์ฑ์ ํธ์ถ
// ์๋ฉธ์ ํธ์ถ
// ์๋ฉธ์ ํธ์ถ
๊ทธ๋ ๊ธฐ์ ์์ ๊ถ์ ์ ๋ฌํ๊ณ ์ถ์๋๋ ๋ค์๊ณผ ๊ฐ์ด ์ฝ๋๋ฅผ ์์ฑํฉ๋๋ค.
โ
์ฝ๋
std::unique_ptr<MyClass> myCalss { mClass };
std::unique_ptr<MyClass> myCalss2 { myCalss.release() };
์ด๋ฐ์์ผ๋ก ์์ฑํด์ผ ์์ ๊ถ์ ์ ๋ฌ ํ ์ ์์ต๋๋ค.
๐ shared_ptr
shared_ptr์ ๊ฒฝ์ฐ ํฌ์ธํฐ์ ๋ํ ์์ ๊ถ์ ์ฌ๋ฌ ๊ฐ์ฒด๊ฐ ๊ฐ์ง ์ ์๋ ์ฅ์ ์ด ์์ต๋๋ค.
โ
์ฝ๋
std::shared_ptr<MyClass> ptr = std::make_shared<MyClass>();
std::shared_ptr<MyClass> ptr2 = ptr;
์ด๋ฐ์์ผ๋ก 2๊ฐ์ shared_ptr์ด ํ๋์ ํฌ์ธํฐ๋ฅผ ๊ด๋ฆฌํฉ๋๋ค.
๋ด๋ถ์ ์ผ๋ก reference counting์ ํตํ์ฌ ํ์ฌ ๋ช ๊ฐ์ ๊ฐ์ฒด๊ฐ ํฌ์ธํฐ๋ฅผ ์ ๊ทผํ๊ณ ์๋์ง ํ์ธํฉ๋๋ค.
๊ทธ๋ก ์ธํด์ ํ๋์ฉ reset์ ํ ๋, ๋ฐ๋ก ๊ฐ์ฒด๊ฐ ์ญ์ ๋๋๊ฒ์ด ์๋๋๋ค.
reference count๊ฐ 1์ฉ ์ค์ด๋ค๊ณ 0์ด๋๋ฉด ๋น๋ก์ ํด์ ๋ฉ๋๋ค.
๐ ์ค๋งํธ ํฌ์ธํฐ ์์ฑ ํจ์
- unique_ptr์ ๊ฒฝ์ฐ make_unique<type>() ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ์์ฑํ๋ ์ด๋ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ด๊ธฐํ ๋ฉ๋๋ค.
- make_unique๊ฐ ์๋ make_unique_for_overwirte<type>() ํจ์๋ฅผ ์ฌ์ฉ์ ์ด๊ธฐํ๊ฐ ์ด๋ฃจ์ด ์ง์ง ์์ต๋๋ค. (C++20)
- shared_ptr์ ๊ฒฝ์ฐ๋ ๋์ผํ๊ฒ make_shared<type>() ํจ์๋ฅผ ์ฌ์ฉ์ ๊ธฐ๋ณธ๊ฐ ์ด๊ธฐํ๊ฐ ๋ฉ๋๋ค.
- ๋์ผํ๊ฒ make_shared_for_overwirte<type>() ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ์ด๊ธฐํ๊ฐ ์ด๋ฃจ์ด์ง์ง ์์ต๋๋ค (C++20)