unique ptr の紹介

46
unique_ptr ののの krustf ( @krustf )

Upload: daisuke-nikura

Post on 28-Jun-2015

3.881 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Unique ptr の紹介

unique_ptr の紹介krustf ( @krustf )

Page 2: Unique ptr の紹介

04/13/2023unique_ptr の紹介 2

自己紹介

XAudio2 普及委員会メンバ(会員 2 名)

第 1 回では XAudio2 について発表

大学ではゲーム製作サークルで活動中

現在 C++0x のお勉強中

Lua 始めました

Page 3: Unique ptr の紹介

04/13/2023unique_ptr の紹介 3

こんな人が創った C++ 言語

Page 4: Unique ptr の紹介

04/13/2023unique_ptr の紹介 4

C++0x って?

今年 FCD が承認された C++ の新標準規格

現行の規格とほぼ 100 %の互換性を持つ

GCC ( GNU Compiler Collection )Microsoft Visual C++

などがすでに対応を始めている

Page 5: Unique ptr の紹介

04/13/2023unique_ptr の紹介 5

諸注意

これから話す内容は現段階で全コンパイラがサポートできていない場合があります

C++ のバージョン比較の定義 現行のバージョン :   C++03 新規格 :   C++0x

Page 6: Unique ptr の紹介

04/13/2023unique_ptr の紹介 6

生ポインタを直接とか(笑)

えー

マジ

生ポインタ?

生ポインタが許される

のは小学生までだよねー

Page 7: Unique ptr の紹介

04/13/2023unique_ptr の紹介 7

バグの温床になりやすい

new したものを 手動で delete とか

new したインスタンスを直接返すとか

生ポインタを扱う事によるうっかりミスのバグがどれだけあるか

Page 8: Unique ptr の紹介

04/13/2023unique_ptr の紹介 8

スマートポインタを使おう!

Page 9: Unique ptr の紹介

04/13/2023unique_ptr の紹介 9

スマートポインタとは

賢い( Smart な)ポインタ

動的確保されたメモリを自動的に deleteしてくれる(リソースを自動解放してくれる)ようなクラス

宣言は違うが使い方はポインタそのもの

Page 10: Unique ptr の紹介

04/13/2023unique_ptr の紹介 10

std::unique_ptr

C++0x で追加されたスマートポインタ

copy は不可能

rvalue reference と move semantics を使ったポインタの「所有権の移動」が可能

Page 11: Unique ptr の紹介

04/13/2023unique_ptr の紹介 11

( ゚Д ゚ ) ハァ ?

Page 12: Unique ptr の紹介

rvalue reference?move semantics?

Page 13: Unique ptr の紹介

04/13/2023unique_ptr の紹介 13

rvalue reference

式の右側にあるものを rvalue と呼ぶ

関数の戻り値などの「一時的で無名なデータ」である rvalue への「参照」

「一時的」なら壊しても構わないはず

Page 14: Unique ptr の紹介

04/13/2023unique_ptr の紹介 14

move semantics

一時オブジェクトをコピーせずにポインタを移動しようという考え方

rvalue として受け取ったものをコピーするのではなく移動 (move) させる

C++03 では auto_ptr が有名

Page 15: Unique ptr の紹介

04/13/2023unique_ptr の紹介 15

早速使ってみる

#include <memory>

std::unique_ptr< int > ptr( new int(5) );

if( ptr ) {

std::cout << *ptr << std::endl;

}

// スコープの末尾で自動的に delete を呼ぶ

Page 16: Unique ptr の紹介

04/13/2023unique_ptr の紹介 16

配列も使える

#include <memory>

std::unique_ptr< int[] > ptr( new int[5] );

for( int i = 0 ; i < 5 ; ++i ) {

ptr[ i ] = i;

}

// delete [] がしっかり呼ばれる

Page 17: Unique ptr の紹介

04/13/2023unique_ptr の紹介 17

( ・ 3 ・ ) ア?ルェー

Page 18: Unique ptr の紹介

04/13/2023unique_ptr の紹介 18

なんで?

new - > delete

new [] - > delete []

どうやって区別してるの .....

Page 19: Unique ptr の紹介

04/13/2023unique_ptr の紹介 19

デリータ指定が可能

unique_ptr にはデリータクラス(オブジェクトを削除担当者)がテンプレート第 2 引数に指定可能

default_delete<T> がデフォルトで指定

Page 20: Unique ptr の紹介

04/13/2023unique_ptr の紹介 20

std::default_delete

namespace std {

template< class T > // 通常

struct default_delete {

void operator()( T* ptr ) const { delete ptr; };

};

template< class T > // 配列

struct default_delete< T[] > {

void operator()( T* ptr ) const { delete [] ptr; };

};

} // namespace std;

Page 21: Unique ptr の紹介

04/13/2023unique_ptr の紹介 21

デリータの指定方法

1. 関数オブジェクト

2. default_delete の特殊化

3. 関数を渡す(ちょっと面倒)

詳細な解説ははてなで記事書いてたのでこっち

http://d.hatena.ne.jp/krustf/20100827/1282915158

Page 22: Unique ptr の紹介

04/13/2023unique_ptr の紹介 22

アプローチ方法がアレなので

Page 23: Unique ptr の紹介

質問形式で幾つか

Page 24: Unique ptr の紹介

Q.元からポインタだったら?

Page 25: Unique ptr の紹介

04/13/2023unique_ptr の紹介 25

特殊ケース(例 . HANDLE 型)

typedef void* HANDLE;といった通常使う型が元々ポインタだったら?

std::unique_ptr< HANDLE, handle_deleter >

ptr( CreateEvent( NULL, FALSE, FALSE, NULL ) );

#=> Error! ' コンストラクタのインスタンスと引数が一致しません '

Page 26: Unique ptr の紹介

A.型からポインタを消せば良いじゃな

Page 27: Unique ptr の紹介

04/13/2023unique_ptr の紹介 27

型からポインタを消す

std::remove_pointer を使う

std::unique_ptr< std::remove_pointer<HANDLE>::type

, ... > ptr( ... );

↓std::unique_ptr< void, ... > ptr( ... );

Page 28: Unique ptr の紹介

Q. 関数の戻り値にできる?

Page 29: Unique ptr の紹介

04/13/2023unique_ptr の紹介 29

unique_ptr で返却したい

生ポインタで返すのは嫌

hoge* create_instance();

hoge* ptr = create_instance();

delete ptr; // 手動解放とか ....

// 解放しわすれでリークとか ....

Page 30: Unique ptr の紹介

A. 可能です

Page 31: Unique ptr の紹介

04/13/2023unique_ptr の紹介 31

関数の戻り値には move が働く

std::unique_ptr<hoge> create_instance();

std::unique_ptr<hoge> ptr = create_instance();

// 自動的に move が働いてポインタが移動される

ptr->func();

// 自動的に削除 , delete ptr; なんて書かなくて済む

Page 32: Unique ptr の紹介

Q. unique_ptr の型が面倒だったら?

Page 33: Unique ptr の紹介

04/13/2023unique_ptr の紹介 33

ややこしい .....std::unique_ptr<

std::remove_pointer<LPDIRECT3DDEVICE9>::type

, com_deleter<LPDIRECT3DDEVICE9>

> create_device();

std::unique_ptr<

std::remove_pointer<LPDIRECT3DDEVICE9>::type

, com_deleter<LPDIRECT3DDEVICE9>

> ptr = create_device();

Page 34: Unique ptr の紹介

A. auto を使おう!

Page 35: Unique ptr の紹介

04/13/2023unique_ptr の紹介 35

auto

C++03 では局所変数についての明確な宣言

コンパイラが知っているので関数の戻り値や初期化値で推論してもらう

std::vector<int> arr;

// it は std::vector<int>::iterator と推論

auto it = arr.begin();

Page 36: Unique ptr の紹介

04/13/2023unique_ptr の紹介 36

戻り値がややこしい時は auto

std::unique_ptr<

std::remove_pointer<LPDIRECT3DDEVICE9>::type

, com_deleter<LPDIRECT3DDEVICE9>

> create_device();

auto device = create_device();

device->Present( NULL, NULL, NULL, NULL );

Page 37: Unique ptr の紹介

結論

Page 38: Unique ptr の紹介

04/13/2023unique_ptr の紹介 38

unique_ptr おいしいです

boost.scoped_ptr デリータ指定できないし , move できない

shared_ptr デリータ指定できるけどコスト的にどうな

の? unique_ptr の使い道を考えると 候補から外す

std::auto_ptr C++0x から deprecated (廃止予定) になっ

Page 39: Unique ptr の紹介

04/13/2023unique_ptr の紹介 39

積極的に使おう

unique_ptr でメモリの手動解放をなくそう

Page 40: Unique ptr の紹介

auto_ptr にはご退場願います

Page 41: Unique ptr の紹介

04/13/2023unique_ptr の紹介 41

今までありがとうございました

auto_ptr

auto_ptr

Page 42: Unique ptr の紹介

auto_ptr さようなら!ご清聴ありがとうございました

Page 43: Unique ptr の紹介

04/13/2023unique_ptr の紹介 43

宣伝

Page 44: Unique ptr の紹介

04/13/2023unique_ptr の紹介 44

祝:プログラミングの魔道書発売!

© 株式会社ロングゲート

Page 45: Unique ptr の紹介

04/13/2023unique_ptr の紹介 45

© 株式会社ロングゲート

Page 46: Unique ptr の紹介

04/13/2023unique_ptr の紹介 46

© 株式会社ロングゲート