SlideShare a Scribd company logo
Effective Modern C++ 스터디
18장, 19장
이데아 게임즈 손진화
시작하기 전에..
• 생 포인터(raw pointer)의 단점
1. 하나의 객체를 가리키는지 배열을
가리키는지 구분하기 어렵다
2. 포인터 사용 후에 가리키는 객체를 삭제해야
되는지 알 수 없다 (소유)
3. 파괴 방법을 알 수 없다
(delete 사용가능 여부)
생 포인터의 단점
4. delete 와 delete [] 중 뭘 써야 하는지 알기
어렵다
5. 파괴는 한 번만 하도록 신경 써야 한다
6. 포인터가 가리키는 객체가 여전히
살아있는지 알 방법이 없다
스마트 포인터
• 앞의 단점들로 인한 버그를 줄이기 위해 나온
포인터
• 생 포인터를 감싸는 형태로 구현
• 생 포인터의 기능을 거의 대부분 지원한다
스마트 포인터의 종류
• auto_ptr
C++ 11 에서 삭제
unique_ptr 로 대체 됨
• unique_ptr
한 명의 소유자만 허용
스마트 포인터의 종류
• shared_ptr
참조 횟수를 계산
• weak_ptr
shared_ptr 가리키는 대상을 가리킬 수 있지만
참조 횟수에 영향을 주지 않음
18장. 소유권 독점 자원의
관리에는 std::unique_ptr 을
사용하라
특징
• 기본적으로 생 포인터와 크기가 같다
• unique_ptr 객체가 사라지면 가리키는
인스턴스도 해제된다
void f() {
unique_ptr<int> a(new int(3));
cout << *a.get() << endl;
} // a에 할당된 메모리가 해제됨!
독점적 소유권
• unique_ptr 은 자신이 가리키고 있는
객체에 대한 소유권을 가지고 있으며 다른
unique_ptr 이 동시에 참조할 수 없다
• 소유권 이동은 가능
예제
class Investment
{
public:
virtual ~Investment();
};
class Stock : public Investment
{
public:
~Stock();
};
class Bond : public Investment
{ // ... 생략 ... };
class RealEstate : public Investment
{ // ... 생략 ... };
예제
template<typename... Ts>
std::unique_ptr<Investment> makeInvestment
(eInvestmentType type, Ts&&... params)
{
std::unique_ptr<Investment> pInv(nullptr);
if (type == eInvestmentType.STOCK)
{
pInv.reset(new Stock(std::forward<Ts>(params)...);
}
// ... 생략 ...
return pInv;
}
예제
template<typename... Ts>
std::unique_ptr<Investment> makeInvestment
(eInvestmentType type, Ts&&... params)
{
std::unique_ptr<Investment> pInv(nullptr);
if (type == eInvestmentType.STOCK)
{
pInv.reset(new Stock(std::forward<Ts>(params)...);
}
// ... 생략 ...
return pInv;
}
예제 – 커스텀 삭제자
auto delInvmt = [](Investment* pInvestment)
{
makeLogEntry(pInvestment);
delete pInvestment;
};
template<typename... Ts>
std::unique_ptr<Investment, decltype(delInvmt)>
makeInvestment(eInvestmentType type,
Ts&&... params)
{
std::unique_ptr<Investment, decltype(delInvmt)>
pInv(nullptr, delInvmt);
// ... 생략 ...
}
예제 – 커스텀 삭제자
auto delInvmt = [](Investment* pInvestment)
{
makeLogEntry(pInvestment);
delete pInvestment;
};
template<typename... Ts>
std::unique_ptr<Investment, decltype(delInvmt)>
makeInvestment(eInvestmentType type,
Ts&&... params)
{
std::unique_ptr<Investment, decltype(delInvmt)>
pInv(nullptr, delInvmt);
// ... 생략 ...
}
예제 (C++ 14)
template<typename... Ts>
std::unique_ptr<Investment, decltype(delInvmt)>
makeInvestment(eInvestmentType type, Ts&&... params)
{
auto delInvmt = [](Investment* pInvestment)
{
makeLogEntry(pInvestment);
delete pInvestment;
};
std::unique_ptr<Investment, decltype(delInvmt)>
pInv(nullptr, delInvmt);
// ... 생략 ...
}
커스텀 삭제자
• 반환 형식의 크기는 함수 포인터의 크기 만큼
증가한다
• 삭제자가 함수 객체일 때는 함수 객체에
저장된 상태의 크기만큼 증가한다
• 갈무리 없는 람다 표현식 권장
배열
• 개별 객체와 배열 객체 포인터 따로 지원
• std::unique_ptr<T>
색인 연산 [] 지원 안됨
• std::unique_ptr<T[]>
->, * 지원 안됨
shared_ptr로 변환
• shared_ptr 로의 변환이 쉽고 효율적임
std::shared_ptr<Investment> sp =
makeInvestment(…);
결론
• unique_ptr은 독점 소유권 의미론을 가진 자
원의 관리를 위한, 작고 빠른 이동전용 똑똑한
포인터이다.
• 기본적으로 자원 파괴는 delete를 통해 일어
나나, 커스텀 삭제자를 지정할 수 도 있다. 상
태 있는 삭제자나 함수 포인터를 사용하면
unique_ptr 객체의 크기가 커진다
결론
• unique_ptr를 shared_ptr로 손쉽게 변환할
수 있다
19장. 소유권 공유 자원의
관리에는 std::shared_ptr를
사용하라
Idea
• 객체 메모리를 일일이 관리하긴 귀찮지만 안
쓸 때 바로 해제하고 싶어!
C++
가비지
콜렉터를
지원하는
언어
shared_ptr
How?
참조횟수
• 해당 자원을 가리키는 shared_ptr 의 개수
• 참조횟수가 0이 되면 자원을 파괴한다
성능
• shared_ptr의 크기는 생 포인터의 2배이다
자원을 가리키는 포인터 +
참조 횟수를 저장하는 포인터
• 참조 횟수를 증감하는 연산은 원자적
연산이다
- 멀티 스레드환경에서도 안전함을
보장해야 하기 때문
- 이동 생성의 경우 횟수가 변하지 않는다
성능
• 참조 횟수를 담는 메모리도 동적으로
할당된다
- 객체는 동적 할당 될 때 참조 횟수를 따로
저장하지 않기 때문
- 내장 형식도 shared_ptr로 선언가능
- std::make_shared를 선언하면 비용을 줄
일 수 있다(커스텀 삭제자 지원 안됨)
커스텀 삭제자
• unique_ptr
선언
unique_ptr<Widget,
decltype(loggingDel)> upw
(new Widget, loggingDel);
타입
std::_ptr<Widget,
lambda []void (Widget *pw)->void>
• 삭제자에 따라 ptr 크기가 변한다
커스텀 삭제자
• shared_ptr
선언
std::shared_ptr<Widget> spw
(new Widget, loggingDel);
타입
std::shared_ptr<Widget>
• 삭제자를 지정해도 크기가 변하지 않는다
커스텀 삭제자
auto costomDeleter1 = [](Widget *pw) {delete pw; };
auto costomDeleter2 = [](Widget *pw) {delete pw; };
unique_ptr<Widget, decltype(costomDeleter1)> upwDeleter1
(new Widget, costomDeleter1);
unique_ptr<Widget, decltype(costomDeleter2)> upwDeleter2
(new Widget, costomDeleter2);
vector<unique_ptr<Widget, decltype(costomDeleter1)>> vupw;
vupw.push_back(upwDeleter1);
vupw.push_back(upwDeleter2); // error!
커스텀 삭제자
auto costomDeleter1 = [](Widget *pw) {delete pw; };
auto costomDeleter2 = [](Widget *pw) {delete pw; };
std::shared_ptr<Widget> spwDeleter1(new Widget, costomDeleter1);
std::shared_ptr<Widget> spwDeleter2(new Widget, costomDeleter2);
vector<shared_ptr<Widget>> vspw;
vspw.push_back(spwDeleter1);
vspw.push_back(spwDeleter2); // ok
제어블록
• shared_ptr 이 관리하는 객체 1개당 제어블
록 1개가 생성된다
제어블록 생성 규칙
• std::make_shared는 항상 제어블록을
생성한다
shared_ptr을 가리키는 객체를 새로
생성하기 때문에 그 객체에 대한 제어블록이
이미 존재할 가능성이 없다
• shared_ptr이나 weak_ptr로부터
shared_ptr을 생성하면 기존 포인터에서
가지고 있는 제어블록을 참고한다
제어블록 생성 규칙
• 고유 소유권 포인터(unique_ptr, auto_ptr)
로부터 shared_ptr 객체를 생성하면
제어블록이 생성된다
- 고유 소유권은 제어블록을 사용하지 않기
때문에 해당 객체에 대한 제어블록이 없다고
보장한다
- 고유 소유권 포인터는 shared_ptr로 이동
하면 해당 객체에 대한 권한을 상실한다
제어블록 생성 규칙
• 생 포인터로 shared_ptr을 생성하면 제어블
록이 생성된다
auto praw = new int(11);
shared_ptr<int> spwFromRaw1(praw);
shared_ptr<int> spwFromRaw2(praw);
// 미정의 행동!
shared_ptr<int> spwGood(new int(11));
// 미정의 행동 방지
this 포인터
class Widget;
vector<shared_ptr<Widget>> processWidgets;
class Widget
{
public:
void process()
{
processWidgets.emplace_back(this);
}
};
// 이미 해당객체를 가리키는 다른 shared_ptr이 있다면 문제가 됨
this 포인터
class Widget;
vector<shared_ptr<Widget>> processWidgets;
class Widget : public enable_shared_from_this<Widget>
{
public:
void process()
{
processWidgets.emplace_back(shared_from_this());
}
};
// Curiously Recurring Template Pattern
// 문제 해결?
this 포인터
class Widget;
vector<shared_ptr<Widget>> processWidgets;
class Widget : public enable_shared_from_this<Widget>
{
public:
template<typename ... Ts>
static shared_ptr<Widget> Create(void)
{
return shared_ptr<Widget>(new Widget());
}
void process()
{
processWidgets.emplace_back(shared_from_this());
}
private:
Widget() {};
};
비싼 비용?
• make_shared로 shared_ptr을 생성하면
제어 블록할당 비용은 무료다
• 제어블록에 있는 가상 함수는 많이 호출되지
않는다
• 원자 연산은 기계어 명령에 대응되기 때문에
비용이 그렇게 크지 않다
• 그래도 부담스럽다면 unique_ptr로 선언한
뒤 업그레이드 하면 된다
그 외
• 단일 객체 관리를 염두에 두고 설계되었기
때문에 operator[]를 제공하지 않는다
결론
• shared_ptr는 임의의 공유 자원의 수명을
편리하게 관리할 수 있는 수단을 제공한다
• 대체로 shared_ptr객체의 크기는
unique_ptr의 두 배이며, 제어 블록에
관련된 추가 부담을 유발하며,
원자적 참조 횟수 조작을 요구한다.
결론
• 자원은 기본적으로 delete를 통해 파괴되나
커스텀 삭제자도 지원한다. 삭제자의 형식은
shared_ptr의 형식에 아무런 영향도 미치지
않는다
• 생 포인터의 형식의 변수로부터
shared_ptr을 생성하는 일은 피해야 한다

More Related Content

What's hot

Effective C++ Chapter 3 Summary
Effective C++ Chapter 3 SummaryEffective C++ Chapter 3 Summary
Effective C++ Chapter 3 Summary
SeungYeonChoi10
 
파이썬 심화
파이썬 심화파이썬 심화
파이썬 심화
Yong Joon Moon
 
파이썬 class 및 function namespace 이해하기
파이썬 class 및 function namespace 이해하기파이썬 class 및 function namespace 이해하기
파이썬 class 및 function namespace 이해하기
Yong Joon Moon
 
파이썬 프로퍼티 디스크립터 이해하기
파이썬 프로퍼티 디스크립터 이해하기파이썬 프로퍼티 디스크립터 이해하기
파이썬 프로퍼티 디스크립터 이해하기
Yong Joon Moon
 
Effective c++chapter3
Effective c++chapter3Effective c++chapter3
Effective c++chapter3
성연 김
 
파이썬 Descriptor이해하기 20160403
파이썬 Descriptor이해하기 20160403파이썬 Descriptor이해하기 20160403
파이썬 Descriptor이해하기 20160403
Yong Joon Moon
 
Effective c++(chapter3,4)
Effective c++(chapter3,4)Effective c++(chapter3,4)
Effective c++(chapter3,4)문익 장
 
파이썬 반복자 생성자 이해하기
파이썬 반복자 생성자 이해하기파이썬 반복자 생성자 이해하기
파이썬 반복자 생성자 이해하기
Yong Joon Moon
 
이펙티브 C++ 스터디
이펙티브 C++ 스터디이펙티브 C++ 스터디
이펙티브 C++ 스터디
quxn6
 
이것이 자바다 Chap. 6 클래스(CLASS)(KOR)
이것이 자바다 Chap. 6 클래스(CLASS)(KOR)이것이 자바다 Chap. 6 클래스(CLASS)(KOR)
이것이 자바다 Chap. 6 클래스(CLASS)(KOR)
MIN SEOK KOO
 
이펙티브 C++ 5,6 장 스터디
이펙티브 C++ 5,6 장 스터디이펙티브 C++ 5,6 장 스터디
이펙티브 C++ 5,6 장 스터디
quxn6
 
이펙티브 C++ 공부
이펙티브 C++ 공부이펙티브 C++ 공부
이펙티브 C++ 공부quxn6
 
이펙티브 C++ (7~9)
이펙티브 C++ (7~9)이펙티브 C++ (7~9)
이펙티브 C++ (7~9)익성 조
 
JavaScript Patterns - Chapter 3. Literals and Constructors
JavaScript Patterns - Chapter 3. Literals and ConstructorsJavaScript Patterns - Chapter 3. Literals and Constructors
JavaScript Patterns - Chapter 3. Literals and Constructors
Hyuncheol Jeon
 
[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitive
[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitive[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitive
[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitive
NAVER D2
 
파이썬 iterator generator 이해하기
파이썬 iterator generator 이해하기파이썬 iterator generator 이해하기
파이썬 iterator generator 이해하기
Yong Joon Moon
 
Effective c++ 정리 chapter 6
Effective c++ 정리 chapter 6Effective c++ 정리 chapter 6
Effective c++ 정리 chapter 6
연우 김
 
Tcpl 14장 예외처리
Tcpl 14장 예외처리Tcpl 14장 예외처리
Tcpl 14장 예외처리
재정 이
 
Effective c++chapter8
Effective c++chapter8Effective c++chapter8
Effective c++chapter8
성연 김
 
프론트엔드스터디 E05 js closure oop
프론트엔드스터디 E05 js closure oop프론트엔드스터디 E05 js closure oop
프론트엔드스터디 E05 js closure oop
Young-Beom Rhee
 

What's hot (20)

Effective C++ Chapter 3 Summary
Effective C++ Chapter 3 SummaryEffective C++ Chapter 3 Summary
Effective C++ Chapter 3 Summary
 
파이썬 심화
파이썬 심화파이썬 심화
파이썬 심화
 
파이썬 class 및 function namespace 이해하기
파이썬 class 및 function namespace 이해하기파이썬 class 및 function namespace 이해하기
파이썬 class 및 function namespace 이해하기
 
파이썬 프로퍼티 디스크립터 이해하기
파이썬 프로퍼티 디스크립터 이해하기파이썬 프로퍼티 디스크립터 이해하기
파이썬 프로퍼티 디스크립터 이해하기
 
Effective c++chapter3
Effective c++chapter3Effective c++chapter3
Effective c++chapter3
 
파이썬 Descriptor이해하기 20160403
파이썬 Descriptor이해하기 20160403파이썬 Descriptor이해하기 20160403
파이썬 Descriptor이해하기 20160403
 
Effective c++(chapter3,4)
Effective c++(chapter3,4)Effective c++(chapter3,4)
Effective c++(chapter3,4)
 
파이썬 반복자 생성자 이해하기
파이썬 반복자 생성자 이해하기파이썬 반복자 생성자 이해하기
파이썬 반복자 생성자 이해하기
 
이펙티브 C++ 스터디
이펙티브 C++ 스터디이펙티브 C++ 스터디
이펙티브 C++ 스터디
 
이것이 자바다 Chap. 6 클래스(CLASS)(KOR)
이것이 자바다 Chap. 6 클래스(CLASS)(KOR)이것이 자바다 Chap. 6 클래스(CLASS)(KOR)
이것이 자바다 Chap. 6 클래스(CLASS)(KOR)
 
이펙티브 C++ 5,6 장 스터디
이펙티브 C++ 5,6 장 스터디이펙티브 C++ 5,6 장 스터디
이펙티브 C++ 5,6 장 스터디
 
이펙티브 C++ 공부
이펙티브 C++ 공부이펙티브 C++ 공부
이펙티브 C++ 공부
 
이펙티브 C++ (7~9)
이펙티브 C++ (7~9)이펙티브 C++ (7~9)
이펙티브 C++ (7~9)
 
JavaScript Patterns - Chapter 3. Literals and Constructors
JavaScript Patterns - Chapter 3. Literals and ConstructorsJavaScript Patterns - Chapter 3. Literals and Constructors
JavaScript Patterns - Chapter 3. Literals and Constructors
 
[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitive
[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitive[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitive
[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitive
 
파이썬 iterator generator 이해하기
파이썬 iterator generator 이해하기파이썬 iterator generator 이해하기
파이썬 iterator generator 이해하기
 
Effective c++ 정리 chapter 6
Effective c++ 정리 chapter 6Effective c++ 정리 chapter 6
Effective c++ 정리 chapter 6
 
Tcpl 14장 예외처리
Tcpl 14장 예외처리Tcpl 14장 예외처리
Tcpl 14장 예외처리
 
Effective c++chapter8
Effective c++chapter8Effective c++chapter8
Effective c++chapter8
 
프론트엔드스터디 E05 js closure oop
프론트엔드스터디 E05 js closure oop프론트엔드스터디 E05 js closure oop
프론트엔드스터디 E05 js closure oop
 

Viewers also liked

voie de synthese ... chemsitry
voie de synthese ... chemsitryvoie de synthese ... chemsitry
voie de synthese ... chemsitry
Mechi Houssem
 
CV Neysa
CV NeysaCV Neysa
CV Neysa
Neysa Nagvenkar
 
Ppt proyecto nacional agrega álvaro gutiérrez pérez-cejuela y diego ramírez...
Ppt proyecto nacional agrega   álvaro gutiérrez pérez-cejuela y diego ramírez...Ppt proyecto nacional agrega   álvaro gutiérrez pérez-cejuela y diego ramírez...
Ppt proyecto nacional agrega álvaro gutiérrez pérez-cejuela y diego ramírez...
Pedro Antonio García-cervigón Jaime
 
reparacion de motores electricos en monterrey www.simsacv.com
reparacion de motores electricos en monterrey www.simsacv.comreparacion de motores electricos en monterrey www.simsacv.com
reparacion de motores electricos en monterrey www.simsacv.com
simsa motores
 
Thanksgiving
ThanksgivingThanksgiving
Thanksgiving
Rodolfo Lopez
 
Presentacion ASPHER Aragón. Asociación de Pacientes de Enfermedades Hematológ...
Presentacion ASPHER Aragón. Asociación de Pacientes de Enfermedades Hematológ...Presentacion ASPHER Aragón. Asociación de Pacientes de Enfermedades Hematológ...
Presentacion ASPHER Aragón. Asociación de Pacientes de Enfermedades Hematológ...
ASPHER Aragón
 
APA style
APA styleAPA style
APA style
jones cho
 
Bio bab 7 kelas XI
Bio bab 7 kelas XIBio bab 7 kelas XI
Bio bab 7 kelas XI
Salma Maulida
 
Health
HealthHealth

Viewers also liked (9)

voie de synthese ... chemsitry
voie de synthese ... chemsitryvoie de synthese ... chemsitry
voie de synthese ... chemsitry
 
CV Neysa
CV NeysaCV Neysa
CV Neysa
 
Ppt proyecto nacional agrega álvaro gutiérrez pérez-cejuela y diego ramírez...
Ppt proyecto nacional agrega   álvaro gutiérrez pérez-cejuela y diego ramírez...Ppt proyecto nacional agrega   álvaro gutiérrez pérez-cejuela y diego ramírez...
Ppt proyecto nacional agrega álvaro gutiérrez pérez-cejuela y diego ramírez...
 
reparacion de motores electricos en monterrey www.simsacv.com
reparacion de motores electricos en monterrey www.simsacv.comreparacion de motores electricos en monterrey www.simsacv.com
reparacion de motores electricos en monterrey www.simsacv.com
 
Thanksgiving
ThanksgivingThanksgiving
Thanksgiving
 
Presentacion ASPHER Aragón. Asociación de Pacientes de Enfermedades Hematológ...
Presentacion ASPHER Aragón. Asociación de Pacientes de Enfermedades Hematológ...Presentacion ASPHER Aragón. Asociación de Pacientes de Enfermedades Hematológ...
Presentacion ASPHER Aragón. Asociación de Pacientes de Enfermedades Hematológ...
 
APA style
APA styleAPA style
APA style
 
Bio bab 7 kelas XI
Bio bab 7 kelas XIBio bab 7 kelas XI
Bio bab 7 kelas XI
 
Health
HealthHealth
Health
 

Similar to Effective modern cpp item18, 19

Boost
BoostBoost
More effective c++ chapter1 2_dcshin
More effective c++ chapter1 2_dcshinMore effective c++ chapter1 2_dcshin
More effective c++ chapter1 2_dcshin
Dong Chan Shin
 
effective c++ chapter 3~4 정리
effective c++ chapter 3~4 정리effective c++ chapter 3~4 정리
effective c++ chapter 3~4 정리
Injae Lee
 
[C++ korea] Effective Modern C++ study item 19 use shared ptr for shared owne...
[C++ korea] Effective Modern C++ study item 19 use shared ptr for shared owne...[C++ korea] Effective Modern C++ study item 19 use shared ptr for shared owne...
[C++ korea] Effective Modern C++ study item 19 use shared ptr for shared owne...
Seok-joon Yun
 
Api design for c++ ch3 pattern
Api design for c++ ch3 patternApi design for c++ ch3 pattern
Api design for c++ ch3 patternjinho park
 
파이썬 스터디 9장
파이썬 스터디 9장파이썬 스터디 9장
파이썬 스터디 9장SeongHyun Ahn
 
Effective c++ 1~8장
Effective c++ 1~8장 Effective c++ 1~8장
Effective c++ 1~8장
Shin heemin
 
Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택
JinTaek Seo
 
[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?
NAVER D2
 
Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심흥배 최
 
Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약
Nam Hyeonuk
 
Ec++ 3,4 summary
Ec++ 3,4 summaryEc++ 3,4 summary
Ec++ 3,4 summarySehyeon Nam
 
Effective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshinEffective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshin
Dong Chan Shin
 
Effective c++ 2
Effective c++ 2Effective c++ 2
Effective c++ 2현찬 양
 
[NDC2016] TERA 서버의 Modern C++ 활용기
[NDC2016] TERA 서버의 Modern C++ 활용기[NDC2016] TERA 서버의 Modern C++ 활용기
[NDC2016] TERA 서버의 Modern C++ 활용기
Sang Heon Lee
 
[C++ Korea 2nd Seminar] C++17 Key Features Summary
[C++ Korea 2nd Seminar] C++17 Key Features Summary[C++ Korea 2nd Seminar] C++17 Key Features Summary
[C++ Korea 2nd Seminar] C++17 Key Features Summary
Chris Ohk
 
2013 C++ Study For Students #1
2013 C++ Study For Students #12013 C++ Study For Students #1
2013 C++ Study For Students #1
Chris Ohk
 
[C++ korea] Effective Modern C++ 신촌 Study Item20,21,23
[C++ korea] Effective Modern C++ 신촌 Study Item20,21,23[C++ korea] Effective Modern C++ 신촌 Study Item20,21,23
[C++ korea] Effective Modern C++ 신촌 Study Item20,21,23
Seok-joon Yun
 
More effective c++ 2
More effective c++ 2More effective c++ 2
More effective c++ 2현찬 양
 
[C++ lab] 6. value,pointer,reference
[C++ lab] 6. value,pointer,reference[C++ lab] 6. value,pointer,reference
[C++ lab] 6. value,pointer,referenceMinGeun Park
 

Similar to Effective modern cpp item18, 19 (20)

Boost
BoostBoost
Boost
 
More effective c++ chapter1 2_dcshin
More effective c++ chapter1 2_dcshinMore effective c++ chapter1 2_dcshin
More effective c++ chapter1 2_dcshin
 
effective c++ chapter 3~4 정리
effective c++ chapter 3~4 정리effective c++ chapter 3~4 정리
effective c++ chapter 3~4 정리
 
[C++ korea] Effective Modern C++ study item 19 use shared ptr for shared owne...
[C++ korea] Effective Modern C++ study item 19 use shared ptr for shared owne...[C++ korea] Effective Modern C++ study item 19 use shared ptr for shared owne...
[C++ korea] Effective Modern C++ study item 19 use shared ptr for shared owne...
 
Api design for c++ ch3 pattern
Api design for c++ ch3 patternApi design for c++ ch3 pattern
Api design for c++ ch3 pattern
 
파이썬 스터디 9장
파이썬 스터디 9장파이썬 스터디 9장
파이썬 스터디 9장
 
Effective c++ 1~8장
Effective c++ 1~8장 Effective c++ 1~8장
Effective c++ 1~8장
 
Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택
 
[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?
 
Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심
 
Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약
 
Ec++ 3,4 summary
Ec++ 3,4 summaryEc++ 3,4 summary
Ec++ 3,4 summary
 
Effective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshinEffective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshin
 
Effective c++ 2
Effective c++ 2Effective c++ 2
Effective c++ 2
 
[NDC2016] TERA 서버의 Modern C++ 활용기
[NDC2016] TERA 서버의 Modern C++ 활용기[NDC2016] TERA 서버의 Modern C++ 활용기
[NDC2016] TERA 서버의 Modern C++ 활용기
 
[C++ Korea 2nd Seminar] C++17 Key Features Summary
[C++ Korea 2nd Seminar] C++17 Key Features Summary[C++ Korea 2nd Seminar] C++17 Key Features Summary
[C++ Korea 2nd Seminar] C++17 Key Features Summary
 
2013 C++ Study For Students #1
2013 C++ Study For Students #12013 C++ Study For Students #1
2013 C++ Study For Students #1
 
[C++ korea] Effective Modern C++ 신촌 Study Item20,21,23
[C++ korea] Effective Modern C++ 신촌 Study Item20,21,23[C++ korea] Effective Modern C++ 신촌 Study Item20,21,23
[C++ korea] Effective Modern C++ 신촌 Study Item20,21,23
 
More effective c++ 2
More effective c++ 2More effective c++ 2
More effective c++ 2
 
[C++ lab] 6. value,pointer,reference
[C++ lab] 6. value,pointer,reference[C++ lab] 6. value,pointer,reference
[C++ lab] 6. value,pointer,reference
 

More from 진화 손

[C++ 20] [P1035R7] Input range adaptors.
[C++ 20] [P1035R7] Input range adaptors.[C++ 20] [P1035R7] Input range adaptors.
[C++ 20] [P1035R7] Input range adaptors.
진화 손
 
[C++ 20] [P0645R10] Text formatting 내용 정리
[C++ 20] [P0645R10] Text formatting 내용 정리[C++ 20] [P0645R10] Text formatting 내용 정리
[C++ 20] [P0645R10] Text formatting 내용 정리
진화 손
 
C++20 constexpr default constructor of std::atomic and std::atomic_flag
C++20 constexpr default constructor of std::atomic and std::atomic_flagC++20 constexpr default constructor of std::atomic and std::atomic_flag
C++20 constexpr default constructor of std::atomic and std::atomic_flag
진화 손
 
[C++ 20][P0325R4] std::to_array() 내용 정리.
[C++ 20][P0325R4] std::to_array() 내용 정리.[C++ 20][P0325R4] std::to_array() 내용 정리.
[C++ 20][P0325R4] std::to_array() 내용 정리.
진화 손
 
C++ 20 Efficient access to std::basic_stringbuf’s buffer
C++ 20 Efficient access to std::basic_stringbuf’s bufferC++ 20 Efficient access to std::basic_stringbuf’s buffer
C++ 20 Efficient access to std::basic_stringbuf’s buffer
진화 손
 
C++20 Remove std::weak_equality and std::strong_equality.pdf
C++20 Remove std::weak_equality and std::strong_equality.pdfC++20 Remove std::weak_equality and std::strong_equality.pdf
C++20 Remove std::weak_equality and std::strong_equality.pdf
진화 손
 
C++20 std::execution::unseq.pdf
C++20 std::execution::unseq.pdfC++20 std::execution::unseq.pdf
C++20 std::execution::unseq.pdf
진화 손
 
C++ 20 class template argument deduction for alias templates
C++ 20 class template argument deduction for alias templatesC++ 20 class template argument deduction for alias templates
C++ 20 class template argument deduction for alias templates
진화 손
 
C++ 20 Make stateful allocator propagation more consistent for operator+(basi...
C++ 20 Make stateful allocator propagation more consistent for operator+(basi...C++ 20 Make stateful allocator propagation more consistent for operator+(basi...
C++ 20 Make stateful allocator propagation more consistent for operator+(basi...
진화 손
 
C++ 20 Unevaluated asm-declaration in constexpr functions
C++ 20 Unevaluated asm-declaration in constexpr functionsC++ 20 Unevaluated asm-declaration in constexpr functions
C++ 20 Unevaluated asm-declaration in constexpr functions
진화 손
 
C++20 Utility functions to implement uses-allocator construction
C++20 Utility functions to implement uses-allocator constructionC++20 Utility functions to implement uses-allocator construction
C++20 Utility functions to implement uses-allocator construction
진화 손
 
C++ 20 std__reference_wrapper for incomplete types
C++ 20 std__reference_wrapper for incomplete typesC++ 20 std__reference_wrapper for incomplete types
C++ 20 std__reference_wrapper for incomplete types
진화 손
 
C++ 20 Stronger Unicode requirements
C++ 20 Stronger Unicode requirementsC++ 20 Stronger Unicode requirements
C++ 20 Stronger Unicode requirements
진화 손
 
C++20 Concepts library
C++20 Concepts libraryC++20 Concepts library
C++20 Concepts library
진화 손
 
C++20 Coroutine
C++20 CoroutineC++20 Coroutine
C++20 Coroutine
진화 손
 
C++ 20 Relaxing the range-for loop customization point finding rules
C++ 20 Relaxing the range-for loop customization point finding rulesC++ 20 Relaxing the range-for loop customization point finding rules
C++ 20 Relaxing the range-for loop customization point finding rules
진화 손
 
C++ 20 Relaxing the structured bindings customization point finding rules
C++ 20 Relaxing the structured bindings customization point finding rulesC++ 20 Relaxing the structured bindings customization point finding rules
C++ 20 Relaxing the structured bindings customization point finding rules
진화 손
 
C++20 explicit(bool)
C++20 explicit(bool)C++20 explicit(bool)
C++20 explicit(bool)
진화 손
 
C++20 std::map::contains
C++20 std::map::containsC++20 std::map::contains
C++20 std::map::contains
진화 손
 
C++20 Comparing unordered containers
C++20 Comparing unordered containersC++20 Comparing unordered containers
C++20 Comparing unordered containers
진화 손
 

More from 진화 손 (20)

[C++ 20] [P1035R7] Input range adaptors.
[C++ 20] [P1035R7] Input range adaptors.[C++ 20] [P1035R7] Input range adaptors.
[C++ 20] [P1035R7] Input range adaptors.
 
[C++ 20] [P0645R10] Text formatting 내용 정리
[C++ 20] [P0645R10] Text formatting 내용 정리[C++ 20] [P0645R10] Text formatting 내용 정리
[C++ 20] [P0645R10] Text formatting 내용 정리
 
C++20 constexpr default constructor of std::atomic and std::atomic_flag
C++20 constexpr default constructor of std::atomic and std::atomic_flagC++20 constexpr default constructor of std::atomic and std::atomic_flag
C++20 constexpr default constructor of std::atomic and std::atomic_flag
 
[C++ 20][P0325R4] std::to_array() 내용 정리.
[C++ 20][P0325R4] std::to_array() 내용 정리.[C++ 20][P0325R4] std::to_array() 내용 정리.
[C++ 20][P0325R4] std::to_array() 내용 정리.
 
C++ 20 Efficient access to std::basic_stringbuf’s buffer
C++ 20 Efficient access to std::basic_stringbuf’s bufferC++ 20 Efficient access to std::basic_stringbuf’s buffer
C++ 20 Efficient access to std::basic_stringbuf’s buffer
 
C++20 Remove std::weak_equality and std::strong_equality.pdf
C++20 Remove std::weak_equality and std::strong_equality.pdfC++20 Remove std::weak_equality and std::strong_equality.pdf
C++20 Remove std::weak_equality and std::strong_equality.pdf
 
C++20 std::execution::unseq.pdf
C++20 std::execution::unseq.pdfC++20 std::execution::unseq.pdf
C++20 std::execution::unseq.pdf
 
C++ 20 class template argument deduction for alias templates
C++ 20 class template argument deduction for alias templatesC++ 20 class template argument deduction for alias templates
C++ 20 class template argument deduction for alias templates
 
C++ 20 Make stateful allocator propagation more consistent for operator+(basi...
C++ 20 Make stateful allocator propagation more consistent for operator+(basi...C++ 20 Make stateful allocator propagation more consistent for operator+(basi...
C++ 20 Make stateful allocator propagation more consistent for operator+(basi...
 
C++ 20 Unevaluated asm-declaration in constexpr functions
C++ 20 Unevaluated asm-declaration in constexpr functionsC++ 20 Unevaluated asm-declaration in constexpr functions
C++ 20 Unevaluated asm-declaration in constexpr functions
 
C++20 Utility functions to implement uses-allocator construction
C++20 Utility functions to implement uses-allocator constructionC++20 Utility functions to implement uses-allocator construction
C++20 Utility functions to implement uses-allocator construction
 
C++ 20 std__reference_wrapper for incomplete types
C++ 20 std__reference_wrapper for incomplete typesC++ 20 std__reference_wrapper for incomplete types
C++ 20 std__reference_wrapper for incomplete types
 
C++ 20 Stronger Unicode requirements
C++ 20 Stronger Unicode requirementsC++ 20 Stronger Unicode requirements
C++ 20 Stronger Unicode requirements
 
C++20 Concepts library
C++20 Concepts libraryC++20 Concepts library
C++20 Concepts library
 
C++20 Coroutine
C++20 CoroutineC++20 Coroutine
C++20 Coroutine
 
C++ 20 Relaxing the range-for loop customization point finding rules
C++ 20 Relaxing the range-for loop customization point finding rulesC++ 20 Relaxing the range-for loop customization point finding rules
C++ 20 Relaxing the range-for loop customization point finding rules
 
C++ 20 Relaxing the structured bindings customization point finding rules
C++ 20 Relaxing the structured bindings customization point finding rulesC++ 20 Relaxing the structured bindings customization point finding rules
C++ 20 Relaxing the structured bindings customization point finding rules
 
C++20 explicit(bool)
C++20 explicit(bool)C++20 explicit(bool)
C++20 explicit(bool)
 
C++20 std::map::contains
C++20 std::map::containsC++20 std::map::contains
C++20 std::map::contains
 
C++20 Comparing unordered containers
C++20 Comparing unordered containersC++20 Comparing unordered containers
C++20 Comparing unordered containers
 

Effective modern cpp item18, 19

  • 1. Effective Modern C++ 스터디 18장, 19장 이데아 게임즈 손진화
  • 2. 시작하기 전에.. • 생 포인터(raw pointer)의 단점 1. 하나의 객체를 가리키는지 배열을 가리키는지 구분하기 어렵다 2. 포인터 사용 후에 가리키는 객체를 삭제해야 되는지 알 수 없다 (소유) 3. 파괴 방법을 알 수 없다 (delete 사용가능 여부)
  • 3. 생 포인터의 단점 4. delete 와 delete [] 중 뭘 써야 하는지 알기 어렵다 5. 파괴는 한 번만 하도록 신경 써야 한다 6. 포인터가 가리키는 객체가 여전히 살아있는지 알 방법이 없다
  • 4. 스마트 포인터 • 앞의 단점들로 인한 버그를 줄이기 위해 나온 포인터 • 생 포인터를 감싸는 형태로 구현 • 생 포인터의 기능을 거의 대부분 지원한다
  • 5. 스마트 포인터의 종류 • auto_ptr C++ 11 에서 삭제 unique_ptr 로 대체 됨 • unique_ptr 한 명의 소유자만 허용
  • 6. 스마트 포인터의 종류 • shared_ptr 참조 횟수를 계산 • weak_ptr shared_ptr 가리키는 대상을 가리킬 수 있지만 참조 횟수에 영향을 주지 않음
  • 7. 18장. 소유권 독점 자원의 관리에는 std::unique_ptr 을 사용하라
  • 8. 특징 • 기본적으로 생 포인터와 크기가 같다 • unique_ptr 객체가 사라지면 가리키는 인스턴스도 해제된다 void f() { unique_ptr<int> a(new int(3)); cout << *a.get() << endl; } // a에 할당된 메모리가 해제됨!
  • 9. 독점적 소유권 • unique_ptr 은 자신이 가리키고 있는 객체에 대한 소유권을 가지고 있으며 다른 unique_ptr 이 동시에 참조할 수 없다 • 소유권 이동은 가능
  • 10. 예제 class Investment { public: virtual ~Investment(); }; class Stock : public Investment { public: ~Stock(); }; class Bond : public Investment { // ... 생략 ... }; class RealEstate : public Investment { // ... 생략 ... };
  • 11. 예제 template<typename... Ts> std::unique_ptr<Investment> makeInvestment (eInvestmentType type, Ts&&... params) { std::unique_ptr<Investment> pInv(nullptr); if (type == eInvestmentType.STOCK) { pInv.reset(new Stock(std::forward<Ts>(params)...); } // ... 생략 ... return pInv; }
  • 12. 예제 template<typename... Ts> std::unique_ptr<Investment> makeInvestment (eInvestmentType type, Ts&&... params) { std::unique_ptr<Investment> pInv(nullptr); if (type == eInvestmentType.STOCK) { pInv.reset(new Stock(std::forward<Ts>(params)...); } // ... 생략 ... return pInv; }
  • 13. 예제 – 커스텀 삭제자 auto delInvmt = [](Investment* pInvestment) { makeLogEntry(pInvestment); delete pInvestment; }; template<typename... Ts> std::unique_ptr<Investment, decltype(delInvmt)> makeInvestment(eInvestmentType type, Ts&&... params) { std::unique_ptr<Investment, decltype(delInvmt)> pInv(nullptr, delInvmt); // ... 생략 ... }
  • 14. 예제 – 커스텀 삭제자 auto delInvmt = [](Investment* pInvestment) { makeLogEntry(pInvestment); delete pInvestment; }; template<typename... Ts> std::unique_ptr<Investment, decltype(delInvmt)> makeInvestment(eInvestmentType type, Ts&&... params) { std::unique_ptr<Investment, decltype(delInvmt)> pInv(nullptr, delInvmt); // ... 생략 ... }
  • 15. 예제 (C++ 14) template<typename... Ts> std::unique_ptr<Investment, decltype(delInvmt)> makeInvestment(eInvestmentType type, Ts&&... params) { auto delInvmt = [](Investment* pInvestment) { makeLogEntry(pInvestment); delete pInvestment; }; std::unique_ptr<Investment, decltype(delInvmt)> pInv(nullptr, delInvmt); // ... 생략 ... }
  • 16. 커스텀 삭제자 • 반환 형식의 크기는 함수 포인터의 크기 만큼 증가한다 • 삭제자가 함수 객체일 때는 함수 객체에 저장된 상태의 크기만큼 증가한다 • 갈무리 없는 람다 표현식 권장
  • 17. 배열 • 개별 객체와 배열 객체 포인터 따로 지원 • std::unique_ptr<T> 색인 연산 [] 지원 안됨 • std::unique_ptr<T[]> ->, * 지원 안됨
  • 18. shared_ptr로 변환 • shared_ptr 로의 변환이 쉽고 효율적임 std::shared_ptr<Investment> sp = makeInvestment(…);
  • 19. 결론 • unique_ptr은 독점 소유권 의미론을 가진 자 원의 관리를 위한, 작고 빠른 이동전용 똑똑한 포인터이다. • 기본적으로 자원 파괴는 delete를 통해 일어 나나, 커스텀 삭제자를 지정할 수 도 있다. 상 태 있는 삭제자나 함수 포인터를 사용하면 unique_ptr 객체의 크기가 커진다
  • 20. 결론 • unique_ptr를 shared_ptr로 손쉽게 변환할 수 있다
  • 21. 19장. 소유권 공유 자원의 관리에는 std::shared_ptr를 사용하라
  • 22. Idea • 객체 메모리를 일일이 관리하긴 귀찮지만 안 쓸 때 바로 해제하고 싶어! C++ 가비지 콜렉터를 지원하는 언어 shared_ptr
  • 23. How? 참조횟수 • 해당 자원을 가리키는 shared_ptr 의 개수 • 참조횟수가 0이 되면 자원을 파괴한다
  • 24. 성능 • shared_ptr의 크기는 생 포인터의 2배이다 자원을 가리키는 포인터 + 참조 횟수를 저장하는 포인터 • 참조 횟수를 증감하는 연산은 원자적 연산이다 - 멀티 스레드환경에서도 안전함을 보장해야 하기 때문 - 이동 생성의 경우 횟수가 변하지 않는다
  • 25. 성능 • 참조 횟수를 담는 메모리도 동적으로 할당된다 - 객체는 동적 할당 될 때 참조 횟수를 따로 저장하지 않기 때문 - 내장 형식도 shared_ptr로 선언가능 - std::make_shared를 선언하면 비용을 줄 일 수 있다(커스텀 삭제자 지원 안됨)
  • 26. 커스텀 삭제자 • unique_ptr 선언 unique_ptr<Widget, decltype(loggingDel)> upw (new Widget, loggingDel); 타입 std::_ptr<Widget, lambda []void (Widget *pw)->void> • 삭제자에 따라 ptr 크기가 변한다
  • 27. 커스텀 삭제자 • shared_ptr 선언 std::shared_ptr<Widget> spw (new Widget, loggingDel); 타입 std::shared_ptr<Widget> • 삭제자를 지정해도 크기가 변하지 않는다
  • 28. 커스텀 삭제자 auto costomDeleter1 = [](Widget *pw) {delete pw; }; auto costomDeleter2 = [](Widget *pw) {delete pw; }; unique_ptr<Widget, decltype(costomDeleter1)> upwDeleter1 (new Widget, costomDeleter1); unique_ptr<Widget, decltype(costomDeleter2)> upwDeleter2 (new Widget, costomDeleter2); vector<unique_ptr<Widget, decltype(costomDeleter1)>> vupw; vupw.push_back(upwDeleter1); vupw.push_back(upwDeleter2); // error!
  • 29. 커스텀 삭제자 auto costomDeleter1 = [](Widget *pw) {delete pw; }; auto costomDeleter2 = [](Widget *pw) {delete pw; }; std::shared_ptr<Widget> spwDeleter1(new Widget, costomDeleter1); std::shared_ptr<Widget> spwDeleter2(new Widget, costomDeleter2); vector<shared_ptr<Widget>> vspw; vspw.push_back(spwDeleter1); vspw.push_back(spwDeleter2); // ok
  • 30. 제어블록 • shared_ptr 이 관리하는 객체 1개당 제어블 록 1개가 생성된다
  • 31. 제어블록 생성 규칙 • std::make_shared는 항상 제어블록을 생성한다 shared_ptr을 가리키는 객체를 새로 생성하기 때문에 그 객체에 대한 제어블록이 이미 존재할 가능성이 없다 • shared_ptr이나 weak_ptr로부터 shared_ptr을 생성하면 기존 포인터에서 가지고 있는 제어블록을 참고한다
  • 32. 제어블록 생성 규칙 • 고유 소유권 포인터(unique_ptr, auto_ptr) 로부터 shared_ptr 객체를 생성하면 제어블록이 생성된다 - 고유 소유권은 제어블록을 사용하지 않기 때문에 해당 객체에 대한 제어블록이 없다고 보장한다 - 고유 소유권 포인터는 shared_ptr로 이동 하면 해당 객체에 대한 권한을 상실한다
  • 33. 제어블록 생성 규칙 • 생 포인터로 shared_ptr을 생성하면 제어블 록이 생성된다 auto praw = new int(11); shared_ptr<int> spwFromRaw1(praw); shared_ptr<int> spwFromRaw2(praw); // 미정의 행동! shared_ptr<int> spwGood(new int(11)); // 미정의 행동 방지
  • 34. this 포인터 class Widget; vector<shared_ptr<Widget>> processWidgets; class Widget { public: void process() { processWidgets.emplace_back(this); } }; // 이미 해당객체를 가리키는 다른 shared_ptr이 있다면 문제가 됨
  • 35. this 포인터 class Widget; vector<shared_ptr<Widget>> processWidgets; class Widget : public enable_shared_from_this<Widget> { public: void process() { processWidgets.emplace_back(shared_from_this()); } }; // Curiously Recurring Template Pattern // 문제 해결?
  • 36. this 포인터 class Widget; vector<shared_ptr<Widget>> processWidgets; class Widget : public enable_shared_from_this<Widget> { public: template<typename ... Ts> static shared_ptr<Widget> Create(void) { return shared_ptr<Widget>(new Widget()); } void process() { processWidgets.emplace_back(shared_from_this()); } private: Widget() {}; };
  • 37. 비싼 비용? • make_shared로 shared_ptr을 생성하면 제어 블록할당 비용은 무료다 • 제어블록에 있는 가상 함수는 많이 호출되지 않는다 • 원자 연산은 기계어 명령에 대응되기 때문에 비용이 그렇게 크지 않다 • 그래도 부담스럽다면 unique_ptr로 선언한 뒤 업그레이드 하면 된다
  • 38. 그 외 • 단일 객체 관리를 염두에 두고 설계되었기 때문에 operator[]를 제공하지 않는다
  • 39. 결론 • shared_ptr는 임의의 공유 자원의 수명을 편리하게 관리할 수 있는 수단을 제공한다 • 대체로 shared_ptr객체의 크기는 unique_ptr의 두 배이며, 제어 블록에 관련된 추가 부담을 유발하며, 원자적 참조 횟수 조작을 요구한다.
  • 40. 결론 • 자원은 기본적으로 delete를 통해 파괴되나 커스텀 삭제자도 지원한다. 삭제자의 형식은 shared_ptr의 형식에 아무런 영향도 미치지 않는다 • 생 포인터의 형식의 변수로부터 shared_ptr을 생성하는 일은 피해야 한다