์ค๋งํธํฌ์ธํฐ
์ค๋งํธํฌ์ธํฐ๋ C++์ ์ถ๊ฐ๋ ๊ธฐ๋ฅ ์ค์ ๋งค์ฐ ์ค์ํ๋ค๊ณ ํ ์ ์์ต๋๋ค. C++์ ์น๋ช ์ ์ธ ๋จ์ ์ค ํ๋๊ฐ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ๋ฅผ ์ง์ ํ๋ ๋ฐ์ ์์ด์ ๋ฆฌ์คํฌ๋ฅผ ๋ ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ๋ฅผ ์๋์ผ๋ก ํด์ฃผ๋ ์ค๋งํธํฌ์ธํฐ๋ก ์ธํด์ ๋ชจ๋ C++์ด ํ์ธต ํ๋ถํด์ก์ต๋๋ค. ์ค๋งํธ ํฌ์ธํฐ๋ ๋ฉ๋ชจ๋ฆฌ ๋์์ ๊ด๋ จ๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋๋ฐ ํฐ ๋์์ ์ฃผ๋ฉฐ, ์์ ๊ด๋ฆฌ๋ฅผ ๋ณด๋ค ์์ ํ๊ฒ ํ๊ณ ์ฝ๋์ ๊ฐ๋ ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ ํฅ์์ํต๋๋ค.
std::unique_ptr
std::unique_ptr์ ๋ ์ ์ ์ผ๋ก ์์ ํ๋ ํฌ์ธํฐ๋ฅผ ๋ํ๋ด๋ฉฐ, ๊ฐ์ฒด์ ๋ํด ๋จ์ผ ์์ ๊ถ์ ๊ฐ์ต๋๋ค. ์ฆ, ์ค์ง ํ๋์ std::unique_ptr๋ง์ด ํน์ ๊ฐ์ฒด๋ฅผ ์์ ํ๊ณ , ์ดํ์๋ ํด๋น ๊ฐ์ฒด์ ์์ ๊ถ์ ๋ค๋ฅธ std::unique_ptr๋ก ์ด์ ํ๊ฑฐ๋, ์์ ๊ถ์ ํฌ๊ธฐํ์ฌ ๊ฐ์ฒด๋ฅผ ์ญ์ ํ ์ ์์ต๋๋ค.
#include <iostream>
#include <memory>
int main() {
// std::unique_ptr ์์ฑ
std::unique_ptr<int> uniquePtr = std::make_unique<int>(42);
// get(): ์๋ณธ ํฌ์ธํฐ์ ๋ํ raw pointer๋ฅผ ๋ฐํ
int* rawPtr = uniquePtr.get();
std::cout << "Raw Pointer: " << rawPtr << std::endl;
// reset(): ํฌ์ธํฐ๋ฅผ ๋ค๋ฅธ ๊ฐ์ฒด๋ก ์ฌํ ๋นํ๊ฑฐ๋, nullptr๋ก ์ด๊ธฐํ
uniquePtr.reset(new int(99));
std::cout << "Reset value: " << *uniquePtr << std::endl;
// swap(): ๋ unique_ptr์ ํฌ์ธํฐ๋ฅผ ๊ตํ
std::unique_ptr<int> anotherUniquePtr = std::make_unique<int>(77);
std::cout << "Before swap - uniquePtr: " << *uniquePtr << ", anotherUniquePtr: " << *anotherUniquePtr << std::endl;
uniquePtr.swap(anotherUniquePtr);
std::cout << "After swap - uniquePtr: " << *uniquePtr << ", anotherUniquePtr: " << *anotherUniquePtr << std::endl;
// release(): ํฌ์ธํฐ ์์ ๊ถ์ ํฌ๊ธฐํ๊ณ raw pointer๋ฅผ ๋ฐํ
int* releasedPtr = uniquePtr.release();
if (!uniquePtr) {
std::cout << "uniquePtr is empty after release." << std::endl;
}
std::cout << "Released Pointer: " << releasedPtr << std::endl;
// unique_ptr ์๋ฉธ ์์๋ ์๋์ผ๋ก ๋์ ํ ๋น๋ ๋ฉ๋ชจ๋ฆฌ๊ฐ ํด์ ๋จ
// releasedPtr๋ ์ด์ raw pointer์ด๋ฏ๋ก ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ง์ ํด์ ํด์ผ ํจ
delete releasedPtr;
return 0;
}
/*
์ถ๋ ฅ๊ฒฐ๊ณผ:
Raw Pointer: 0x...
Reset value: 99
Before swap - uniquePtr: 99, anotherUniquePtr: 77
After swap - uniquePtr: 77, anotherUniquePtr: 99
uniquePtr is empty after release.
Released Pointer: 0x...
*/
std::shared_ptr
std::shared_ptr์ C++ ์ค๋งํธ ํฌ์ธํฐ ์ค ํ๋๋ก, ์ฌ๋ฌ ๊ฐ์ std::shared_ptr๋ค์ด ํ๋์ ๊ฐ์ฒด๋ฅผ ๊ณต์ ์์ ํ๋ ํํ๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค. ๊ฐ std::shared_ptr๋ค์ ๊ฐ์ฒด์ ๋ํ ์ฐธ์กฐ ์นด์ดํธ๋ฅผ ์ ์งํ๊ณ , ๊ฐ์ฒด์ ์ฐธ์กฐ ์นด์ดํธ๊ฐ 0์ด ๋๋ฉด ์๋์ผ๋ก ๊ฐ์ฒด๊ฐ ๋ฉ๋ชจ๋ฆฌ์์ ํด์ ๋ฉ๋๋ค. ์ด๋ฌํ ๊ณต์ ์์ ๋ฐฉ์์ผ๋ก ์ธํด ๊ฐ์ฒด์ ์๋ช ์ ํจ๊ณผ์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
std::shared_ptr์์ ์ฌ์ฉ๋๋ ์ฃผ์ ๋ฉ์๋๋ค์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
std::shared_ptr ์์ฑ ๋ฐ ์ด๊ธฐํ
std::shared_ptr<T>: ๊ธฐ๋ณธ ์์ฑ์๋ก ์ด๊ธฐํ๋ ๋น std::shared_ptr ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค.
std::shared_ptr<T>(args...): args...๋ก ์ ๋ฌ๋ ์ธ์๋ค๋ก T ํ์
์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ํด๋น ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๋ std::shared_ptr ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค.
std::make_shared<T>(args...): args...๋ก ์ ๋ฌ๋ ์ธ์๋ค๋ก T ํ์
์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ํด๋น ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๋ std::shared_ptr ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค. std::make_shared๋ ๋ฉ๋ชจ๋ฆฌ ํ ๋น๊ณผ ๊ฐ์ฒด ์ด๊ธฐํ๋ฅผ ํ๋์ ๋จ์ผ ์ฐ์ฐ์ผ๋ก ์ํํ์ฌ ์ค๋ฒํค๋๋ฅผ ์ค์ผ ์ ์์ต๋๋ค.
์์ ๊ถ ๋ฐ ์ฐธ์กฐ ์นด์ดํธ
use_count(): ํ์ฌ ๊ฐ์ฒด์ ์ฐธ์กฐ ์นด์ดํธ๋ฅผ ๋ฐํํฉ๋๋ค.
unique(): ์ฐธ์กฐ ์นด์ดํธ๊ฐ 1์ด๋ฉด true๋ฅผ ๋ฐํํ๊ณ , ๊ทธ๋ ์ง ์์ผ๋ฉด false๋ฅผ ๋ฐํํฉ๋๋ค.
get(): ์๋ณธ ํฌ์ธํฐ์ ๋ํ raw pointer๋ฅผ ๋ฐํํฉ๋๋ค.
์์ ๊ถ ์ด์
reset(): std::shared_ptr์ ์์ ๊ถ์ ํฌ๊ธฐํ๊ณ , ์ฐธ์กฐํ๋ ๊ฐ์ฒด์ ์ฐธ์กฐ ์นด์ดํธ๋ฅผ ๊ฐ์์ํต๋๋ค. ์ด๋ก ์ธํด ๊ฐ์ฒด์ ์ฐธ์กฐ ์นด์ดํธ๊ฐ 0์ด ๋๋ฉด ์๋์ผ๋ก ๊ฐ์ฒด๊ฐ ์ญ์ ๋ฉ๋๋ค.
reset(T* ptr): std::shared_ptr์ ์์ ๊ถ์ ์๋ก์ด ํฌ์ธํฐ ptr๋ก ์ด์ ํฉ๋๋ค. ์ด๋ฏธ ๋ค๋ฅธ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํค๊ณ ์๋ ๊ฒฝ์ฐ์๋ ํด๋น ๊ฐ์ฒด์ ์ฐธ์กฐ ์นด์ดํธ๊ฐ ๊ฐ์ํ๊ณ , ์๋ก์ด ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํค๊ฒ ๋ฉ๋๋ค.
๊ณต์ ๋ฐ ๋น๊ณต์ std::shared_ptr์ ์์ฑ ๋ฐ ๋น๊ต
std::shared_ptr<T>(const std::shared_ptr<T>& r): r์ด ๊ฐ๋ฆฌํค๋ ๊ฐ์ฒด๋ฅผ ๊ณต์ ์์ ํ๋ std::shared_ptr์ ์์ฑํฉ๋๋ค.
std::shared_ptr<T>(std::shared_ptr<T>&& r) noexcept: r์ด ๊ฐ๋ฆฌํค๋ ๊ฐ์ฒด๋ฅผ ๊ณต์ ์์ ํ๋ std::shared_ptr์ ์์ฑํฉ๋๋ค. ์ด๋ ์์ฑ์๋ก, noexcept ์์ฑ์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
std::shared_ptr<T>(std::weak_ptr<T> r): r์ด ๊ฐ๋ฆฌํค๋ ๊ฐ์ฒด๋ฅผ ๊ณต์ ์์ ํ๋ std::shared_ptr์ ์์ฑํฉ๋๋ค. ์ด ๋, r์ด ๊ฐ๋ฆฌํค๋ ๊ฐ์ฒด๊ฐ ์ ํจํ์ง ์์ผ๋ฉด ๋น std::shared_ptr์ด ์์ฑ๋ฉ๋๋ค.
operator==, operator!=: std::shared_ptr ๊ฐ์ฒด๋ค์ ๋น๊ตํฉ๋๋ค.
๋ค๋ฅธ ์ค๋งํธ ํฌ์ธํฐ์์ ์ํธ์์ฉ
std::shared_ptr์ std::weak_ptr๊ณผ ํจ๊ป ์ฌ์ฉ๋์ด ๋ฃจํ๋ฅผ ๋ฐฉ์งํ๊ณ dangling pointer๋ฅผ ์๋ฐฉํ๋ ๋ฐ์ ์ ์ฉํฉ๋๋ค.
std::shared_ptr์ std::unique_ptr๋ก๋ถํฐ ์์ฑํ ์ ์์ต๋๋ค.
#include <iostream>
#include <memory>
int main() {
std::shared_ptr<int> sharedPtr1 = std::make_shared<int>(42);
std::cout << "sharedPtr1 use_count: " << sharedPtr1.use_count() << std::endl; // 1
std::shared_ptr<int> sharedPtr2 = sharedPtr1;
std::cout << "sharedPtr1 use_count: " << sharedPtr1.use_count() << std::endl; // 2
std::cout << "sharedPtr2 use_count: " << sharedPtr2.use_count() << std::endl; // 2
sharedPtr1.reset();
std::cout << "sharedPtr1 use_count: " << sharedPtr1.use_count() << std::endl; // 0 (sharedPtr1์ ๋ ์ด์ ๊ฐ์ฒด๋ฅผ ์์ ํ์ง ์์)
std::cout << "sharedPtr2 use_count: " << sharedPtr2.use_count() << std::endl; // 1
return 0;
}
/*
์ถ๋ ฅ๊ฒฐ๊ณผ:
sharedPtr1 use_count: 1
sharedPtr1 use_count: 2
sharedPtr2 use_count: 2
sharedPtr1 use_count: 0
sharedPtr2 use_count: 1
*/
์ ์์ ์์๋ std::shared_ptr์ ์์ฑ, ์์ ๊ถ ์ด์ , ์ฐธ์กฐ ์นด์ดํธ ๋ฑ์ ๊ธฐ๋ฅ์ ๋ณด์ฌ์ฃผ์์ต๋๋ค. ๋ ๊ฐ์ std::shared_ptr ๊ฐ์ฒด๊ฐ ํ๋์ ๊ฐ์ฒด๋ฅผ ๊ณต์ ์์ ํ๊ณ ์์ผ๋ฉฐ, ํด๋น ๊ฐ์ฒด์ ์ฐธ์กฐ ์นด์ดํธ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค. ์์ ๊ถ์ ์ด์ ํ๋ฉด์ ์ฐธ์กฐ ์นด์ดํธ๊ฐ ๋ณ๊ฒฝ๋๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
std::weak_ptr
std::weak_ptr์ ๊ฐ์ฒด๋ฅผ ๊ณต์ ํ์ง๋ง ์ฐธ์กฐ ์นด์ดํธ๋ฅผ ์ฆ๊ฐ์ํค์ง ์๋ ์ค๋งํธ ํฌ์ธํฐ์ ๋๋ค. std::weak_ptr์ ์ฃผ๋ก std::shared_ptr์ ํจ๊ป ์ฌ์ฉ๋๋ฉฐ, std::weak_ptr๋ฅผ ํตํด ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๋ ๋์ ์ฐธ์กฐ ์นด์ดํธ๋ ์ฆ๊ฐํ์ง ์๊ธฐ ๋๋ฌธ์ ๊ฐ์ฒด์ ์๋ช ์ด std::weak_ptr์ ์ํฅ์ ๋ฐ์ง ์์ต๋๋ค.
weak_ptr์ ํน์ง์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
๊ฐ์ฒด ์์ ๊ถ์ด ์์
std::weak_ptr์ ๊ฐ์ฒด์ ๋ํ ์์ ๊ถ์ ๊ฐ์ง ์์ต๋๋ค. ์ฆ, std::weak_ptr๋ง์ผ๋ก๋ ๊ฐ์ฒด๊ฐ ๋ฉ๋ชจ๋ฆฌ์์ ์ญ์ ๋์ง ์์ต๋๋ค. ๋จ์ง ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๊ณ ๊ด์ฐฐํ๋ ์ญํ ์ ํฉ๋๋ค.
์ฐธ์กฐํ๋ ๊ฐ์ฒด์ ์๋ช ์ฒดํฌ
std::weak_ptr๋ std::shared_ptr๊ฐ ์๋ ๋ค๋ฅธ ์ค๋งํธ ํฌ์ธํฐ์ ์์ ์์ผ ์ ์์ต๋๋ค. ๋๋ฌธ์ std::weak_ptr๊ฐ ์ฐธ์กฐํ๋ ๊ฐ์ฒด๊ฐ ์ฌ์ ํ ์ ํจํ์ง ํ์ธํด์ผ ํฉ๋๋ค.
std::weak_ptr๋ก๋ถํฐ std::shared_ptr ์์ฑ
std::weak_ptr๋ก๋ถํฐ std::shared_ptr์ ์์ฑํ์ฌ ๊ฐ์ฒด์ ๋ํ ์์ ์์ ๊ถ์ ์ป์ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ๊ฐ์ฒด๊ฐ ์ฌ์ ํ ์ ํจํ์ง ์ฒดํฌํ ๋ค ์ ํจํ ๊ฒฝ์ฐ์๋ง ๊ฐ์ฒด์ ์ ๊ทผํ ์ ์์ต๋๋ค.
std::weak_ptr์ ์์ฑ๊ณผ ์๋ฉธ
std::weak_ptr์ std::shared_ptr์ผ๋ก๋ถํฐ ์์ฑ๋๊ฑฐ๋, std::shared_ptr๋ก๋ถํฐ ์์ฑ๋ ํ std::weak_ptr๋ก๋ถํฐ ์์ฑ๋ ์ ์์ต๋๋ค. std::weak_ptr์ด ๋ ์ด์ ์ ํจํ์ง ์๋ค๋ฉด ๊ฐ์ฒด์ ๋ํ ์์ ๊ถ์ด ๋ ์ด์ ์๋ค๋ ๋ป์ด๋ฉฐ, ๊ฐ์ฒด๊ฐ ์ญ์ ๋์๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
#include <iostream>
#include <memory>
int main() {
std::shared_ptr<int> sharedPtr = std::make_shared<int>(42);
std::weak_ptr<int> weakPtr = sharedPtr;
// weakPtr๋ก๋ถํฐ sharedPtr ์์ฑ
if (auto lockedSharedPtr = weakPtr.lock()) {
std::cout << "Weak pointer is valid. Value: " << *lockedSharedPtr << std::endl;
} else {
std::cout << "Weak pointer is expired." << std::endl;
}
// sharedPtr๋ฅผ resetํ๊ณ weakPtr๋ก๋ถํฐ ์์ฑํ sharedPtr ์ ๊ทผ ์๋
sharedPtr.reset();
if (auto lockedSharedPtr = weakPtr.lock()) {
std::cout << "Weak pointer is valid. Value: " << *lockedSharedPtr << std::endl;
} else {
std::cout << "Weak pointer is expired." << std::endl;
}
return 0;
}
/*
์ถ๋ ฅ๊ฒฐ๊ณผ:
Weak pointer is valid. Value: 42
Weak pointer is expired.
*/
std::weak_ptr์ ์ด์ฉํ์ฌ std::shared_ptr๋ฅผ ๊ด์ฐฐํฉ๋๋ค. lock() ํจ์๋ฅผ ์ฌ์ฉํ์ฌ std::weak_ptr๊ฐ ์ฌ์ ํ ์ ํจํ์ง ์ฒดํฌํ๊ณ , ์ ํจํ ๊ฒฝ์ฐ์๋ง std::shared_ptr๋ก๋ถํฐ ์์ ์์ ๊ถ์ ์ป์ด์ ๊ฐ์ฒด์ ์ ๊ทผํฉ๋๋ค. ๋ง์ฝ std::weak_ptr์ด ๋ ์ด์ ์ ํจํ์ง ์๋ค๋ฉด, ์ฆ ํด๋น ๊ฐ์ฒด๊ฐ ์ญ์ ๋์๋ค๋ฉด lock() ํจ์๋ nullptr๋ฅผ ๋ฐํํ๊ฒ ๋ฉ๋๋ค. ์ด๋ ๊ฒ lock() ํจ์๋ฅผ ํตํด ์ํ ์ฐธ์กฐ๋ฅผ ๋ฐฉ์งํ๋ฉด์ ๊ฐ์ฒด๋ฅผ ์์ ํ๊ฒ ๊ด์ฐฐํ ์ ์์ต๋๋ค.
'ํ๋ก๊ทธ๋๋ฐ ์ธ์ด > C++ ์์ฉ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[c++] constexpr์ ๋ชจ๋ ๊ฒ (0) | 2024.08.21 |
---|---|
ํด๋์ค์ ํฌ๊ธฐ์ ๋ฉ๋ชจ๋ฆฌ ๊ตฌ์กฐ (0) | 2023.09.14 |
[STL] std::tuple, std::make_tuple, std::tie, std::ignore (0) | 2023.08.04 |
[STL][functional] std::bind, std::function (0) | 2023.06.08 |
[STL] utility : minmax, move, forward, swap (0) | 2023.06.04 |
๋๊ธ