고급 사용 패턴
사용자 정의 소멸자
스마트 포인터는 사용자 정의 메모리 관리 전략을 허용합니다.
#include <memory>
#include <iostream>
// 파일 처리를 위한 사용자 정의 소멸자
void fileDeleter(FILE* file) {
if (file) {
std::cout << "파일 닫기\n";
fclose(file);
}
}
void demonstrateCustomDeleter() {
// 사용자 정의 소멸자를 사용하는 unique_ptr
std::unique_ptr<FILE, decltype(&fileDeleter)>
file(fopen("example.txt", "r"), fileDeleter);
}
소멸자 유형
| 소멸자 유형 |
사용 사례 |
예시 |
| 함수 포인터 |
간단한 자원 정리 |
파일 핸들 |
| 람다 |
복잡한 정리 로직 |
네트워크 소켓 |
| 펑터 |
상태 있는 삭제 |
사용자 정의 자원 관리 |
스마트 포인터를 사용한 팩토리 메서드
class BaseResource {
public:
virtual ~BaseResource() = default;
virtual void process() = 0;
};
class ConcreteResource : public BaseResource {
public:
void process() override {
std::cout << "자원 처리\n";
}
};
class ResourceFactory {
public:
// unique_ptr 를 반환하는 팩토리 메서드
static std::unique_ptr<BaseResource> createResource() {
return std::make_unique<ConcreteResource>();
}
};
팩토리 메서드 흐름
graph TD
A[팩토리 메서드 호출] --> B[파생 객체 생성]
B --> C[unique_ptr 반환]
C --> D[자동 메모리 관리]
다형성 컬렉션
#include <vector>
#include <memory>
class Shape {
public:
virtual double area() = 0;
virtual ~Shape() = default;
};
class Circle : public Shape {
double radius;
public:
Circle(double r) : radius(r) {}
double area() override { return 3.14 * radius * radius; }
};
void demonstratePolymorphicCollection() {
std::vector<std::unique_ptr<Shape>> shapes;
shapes.push_back(std::make_unique<Circle>(5.0));
shapes.push_back(std::make_unique<Circle>(7.0));
for (const auto& shape : shapes) {
std::cout << "면적: " << shape->area() << std::endl;
}
}
고급 소유권 패턴
공유 소유권 시나리오
graph LR
A[여러 소유자] --> B[shared_ptr]
B --> C[참조 카운팅]
C --> D[자동 정리]
스레드 안전 참조 카운팅
#include <memory>
#include <thread>
class ThreadSafeResource {
public:
std::shared_ptr<int> data;
ThreadSafeResource() {
data = std::make_shared<int>(42);
}
};
void threadFunction(std::shared_ptr<ThreadSafeResource> resource) {
// 스레드 안전한 공유 자원 접근
std::cout << *resource->data << std::endl;
}
성능 고려 사항
| 스마트 포인터 |
오버헤드 |
사용 사례 |
unique_ptr |
최소 |
단일 소유권 |
shared_ptr |
중간 |
공유 소유권 |
weak_ptr |
낮음 |
순환 참조 해제 |
LabEx 최적화 사항
LabEx 에서는 다음을 권장합니다.
- 가능한 가장 제한적인 스마트 포인터를 사용합니다.
- 기본적으로
unique_ptr를 사용합니다.
shared_ptr는 필요에 따라 사용합니다.
- 복잡한 자원에는 사용자 정의 소멸자를 활용합니다.
주요 내용
- 스마트 포인터는 고급 메모리 관리를 지원합니다.
- 사용자 정의 소멸자는 유연한 자원 처리를 제공합니다.
- 다형성 컬렉션은 스마트 포인터의 이점을 얻습니다.
- 각 시나리오에 적합한 스마트 포인터를 선택합니다.