Boostのスマートなポインタを使ってみる

Slides:



Advertisements
Similar presentations
アルゴリズムとプログラミン グ (Algorithms and Programming) 第6回:クラスとインスタンス クラスの宣言 アクセス修飾子 インスタンスの生成 (new キーワード) this キーワード フィールドとメソッドの実際の定義と使い 方 クラスの宣言 アクセス修飾子 インスタンスの生成.
Advertisements

オブジェクト指向 言語 論 第八回 知能情報学部 新田直也. 多相性(最も単純な例) class A { void m() { System.out.println( “ this is class A ” ); } } class A1 extends A { void m() { System.out.println(
独習JAVA Chapter 6 6.6 クラスの修飾子 6.7 変数の修飾子 結城 隆. 6.6 クラスの修飾 abstract インスタンス化できないクラス。1つまたは複数のサブクラスで 実装してはじめてインスタンス化できる。 final 継承されたくないことを明示する。これ以上機能拡張 / 変更でき.
わんくま同盟 横浜勉強会 #1 - C++ Day Boost とその実装技術 ~ Boost の薄い話から濃い話まで~
プログラミング第5回 1 while ループ 文字列の操作
6.4継承とメソッド 6.5継承とコンストラクタ 11月28日 時田 陽一
~手続き指向からオブジェクト指向へ(Ⅰ)~
とても使いやすい Boost の serialization
アルゴリズムとプログラミング (Algorithms and Programming)
とても使いやすい Boost の serialization
.NET Frameworkにおける マネージヒープと ガベージコレクション
第2回:Javaの変数と型の宣言 プログラミングII 2007年10月2日.
アルゴリズムとデータ構造 2011年6月13日
構造体.
アルゴリズムとプログラミング (Algorithms and Programming)
繰り返し プログラミング 第4回 繰り返し プログラミング第4回.
第20章 Flyweight ~同じものを共有して無駄をなくす~
補足説明.
プログラミング論 関数ポインタ と 応用(qsort)
プログラミング言語入門 手続き型言語としてのJava
アルゴリズムとプログラミング (Algorithms and Programming)
第9章 例外処理,パッケージ 9.1 例外処理 9.2 ガーベッジコレクション.
オブジェクト指向 プログラミング 第八回 知能情報学部 新田直也.
独習JAVA 6.8 コンストラクタの修飾子 6.9 メソッドの修飾子 6.10 ObjectクラスとClassクラス 11月28日(金)
オブジェクト指向 プログラミング 第十一回 知能情報学部 新田直也.
オブジェクト指向 プログラミング 第十三回 知能情報学部 新田直也.
暗黙的に型付けされる構造体の Java言語への導入
第11週:super/subクラス、継承性、メソッド再定義
2005年度 データ構造とアルゴリズム 第3回 「C言語の復習:再帰的データ構造」
コンパイラ 2012年11月15日
アルゴリズムとデータ構造 補足資料5-1 「メモリとポインタ」
5.9 メソッドのオーバーロード 5.10 変数の引渡し 2003/11/21 紺野憲一
C#言語ソースプログラムの原型 C言語 C#言語 Hello World! Hello Students! オマジナイ! 適当なクラス名
オブジェクト指向言語論 第十一回 知能情報学部 新田直也.
一時的な型 長谷川啓
オブジェクト指向 プログラミング 第十ニ回 知能情報学部 新田直也.
オブジェクト指向プログラミングと開発環境
オブジェクト指向言語論 第十一回 知能情報学部 新田直也.
計算機プログラミングI 第5回 配列 文字列(Stringクラス) mainの引数 配列の利用例
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング言語論 第六回 理工学部 情報システム工学科 新田直也.
アルゴリズムとプログラミング (Algorithms and Programming)
参照されないリテラル 長谷川啓
オブジェクト指向 プログラミング 第九回 知能情報学部 新田直也.
プログラミング言語論 第十三回 理工学部 情報システム工学科 新田直也.
オブジェクト指向 プログラミング 第八回 知能情報学部 新田直也.
プログラミング言語論 第十一回 理工学部 情報システム工学科 新田直也.
計算機プログラミングI 第3回 プリミティブ値 クラスメソッド クラス変数 式と演算 変数の利用
アルゴリズムとデータ構造 2012年6月11日
nativeの基礎知識 「ポインタ」てなによ!?
Chapter 5 5.5 thisキーワード 5.6 インスタンス変数とインスタンスメソッド 結城 隆
アルゴリズムとデータ構造1 2009年6月15日
ネットワーク・プログラミング Cプログラミングの基礎.
オブジェクト指向言語論 第五回 知能情報学部 新田直也.
メンバとメソッド C言語の構造体 変数の集まり C#言語のクラス + それを処理する関数の集まり フィールド または メンバ変数 メンバ
JAVA入門⑥ クラスとインスタンス.
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
cp-2. 属性,アクセサ (C++ オブジェクト指向プログラミング入門)
アルゴリズムとデータ構造 2010年6月17日
ソフトウェア工学 知能情報学部 新田直也.
オブジェクト指向言語論 第七回 知能情報学部 新田直也.
演算子のオーバーロード.
Javaとは Javaとはオブジェクト指向言語でJava VM(Java仮想マシン)と呼ばれるプログラム上で動作します。
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング演習II 2004年11月 2日(第3回) 理学部数学科・木村巌.
TList リスト構造とは? 複数のデータを扱うために、 データの内容と、次のデータへのポインタを持つ構造体を使う。
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
オブジェクト指向言語論 第十回 知能情報学部 新田直也.
計算機プログラミングI 第2回 2002年10月17日(木) 履習登録 複習 ライブラリの利用 (2.6-7) 式・値・代入 (2.6-8)
計算機プログラミングI 第5回 2002年11月7日(木) 配列: 沢山のデータをまとめたデータ どんなものか どうやって使うのか
Presentation transcript:

Boostのスマートなポインタを使ってみる ゼグラム

HM:ゼグラム(本名:清水 政宏、年齢:44歳) お仕事:北九州市小倉でシステム開発 4月以降はたぶん福岡市でお仕事 自己紹介 HM:ゼグラム(本名:清水 政宏、年齢:44歳) お仕事:北九州市小倉でシステム開発 4月以降はたぶん福岡市でお仕事 趣味:ガジェット(オモチャ)探し・集め 一番長く使った言語:C/C++ あまり好きではない言語:C/C++ 好きな言語:Ruby

C/C++の変数とC#の変数の違い インスタンスがスタック上に確保される値型① int, double, char, byteなどstring以外の基本型とstruct定義したユーザ型 struct UserData { public int p1; public double p2; } int a = 10; UserData b; // structなのでインスタンスはスタック

C/C++の変数とC#の変数の違い インスタンスがスタック上に確保される値型② 基本的に全てのローカル変数のインスタンスは、スタック上に確保される class UserData { public: int p1; double p2; }; int a = 10; UserData b; // クラスでもインスタンスはスタック

C/C++の変数とC#の変数の違い ヒープ上に確保される変数① stringや、classで定義したユーザ型はヒープ上に作成される class UserData { public int p1; public double p2; } // newでインスタンスをヒープ上に確保し // スタック上の参照変数にアドレスを代入 UserData a = new UserData();

C/C++の変数とC#の変数の違い ヒープ上に確保される変数② C++言語の場合はstructやclassに関係なく全ての型をnewでヒープ上から確保しポインタ変数に確保したアドレスを入れることで、C#の参照型と同じように使用する struct UserData { int p1; double p2; }; UserData* a = new UserData();

C#の値型変数では、多態性を実現することはできない。 C#で多態性を実現するには、参照型変数を使用しなければならない。

C++でも値型ある通常変数では、多態性は実現できない。 C++で多態性を実現するには、ポインタ変数を使用しなければならない。

C++のnewでヒープから確保したメモリに対しての管理はプログラマが自力で行わなければならない。 C++にはGCが無い 昔ながらのC言語との互換性を重視しているC++/Objective-Cには、自動的にメモリ管理を行ってくれるGC(ガベージコレクション)が存在しない。 C++のnewでヒープから確保したメモリに対しての管理はプログラマが自力で行わなければならない。 オブジェクト使用言語としてGCが無いのは不便でしょうがない。

GCの内部処理の方式には色々な方法が存在するが、通常のGCはマークアンドスイープと呼ばれる方法をベースにしている。

マークアンドスイープの例① スタック ヒープ class UserData { public int d; } static vod Main(string[] args) { UserData ud1 = new UserData();←(A) { UserData ud2 = new UserData();←(B) UserData r1 = ud1; UserData r2 = ud2; r2 r1 (B) ud2 (A) ud1

マークアンドスイープの例② スタック ヒープ class UserData { public int d; } static vod Main(string[] args) { UserData ud1 = new UserData();←(A) { UserData ud2 = new UserData();←(B) UserData r1 = ud1; UserData r2 = ud2; }← ここでGCが動いたとして r2 r1 (B) ud2 (A) ud1

マークアンドスイープの例③ スタック ヒープ class UserData { public int d; } static vod Main(string[] args) { UserData ud1 = new UserData();←(A) { UserData ud2 = new UserData();←(B) UserData r1 = ud1; UserData r2 = ud2; }← ここでGCが動いたとして r2 r1 (B) ud2 (A) ud1

GCはスタック上に残っている参照変数から繋がっている(使用中)のメモリに対してマークし、残った非使用メモリに対してスイープする。 C++でGCを実現できないのはなぜ① GCはスタック上に残っている参照変数から繋がっている(使用中)のメモリに対してマークし、残った非使用メモリに対してスイープする。 C言語では、スタック上格納された変数のタイプが通常の変数なのかポインタ変数なのか判断できない。

C言語との互換性を重視しているC++/Objective-Cでも同じく通常変数とポインタ変数を区別できない。 C++でGCを実現できないのはなぜ② C言語との互換性を重視しているC++/Objective-Cでも同じく通常変数とポインタ変数を区別できない。 int a = 10; int* b = new int; 変数a, bのどちらがポインタでどちらが通常変数か判断できない b b a

C++の次期標準規格C++0xでも最初GCを導入する方向で進んでいたが、現在の資料では直接的な導入は見送られた。 AppleのMacOS X 10.5 用のObjective-C 2.0では、GCを導入済みらしい。(但しiPhone用の開発ツールではGCは使えないらしい) C++の次期標準規格C++0xでも最初GCを導入する方向で進んでいたが、現在の資料では直接的な導入は見送られた。 C/C++では、保守的GCとう考え方で作成されたBoehm GCが存在する。このGCはC言語でも利用可能。

ガベージコレクタと同じメモリ管理機能を、ライブラリと使用できるようにしたもの スマートポインタとは ガベージコレクタと同じメモリ管理機能を、ライブラリと使用できるようにしたもの C++では標準ライブラリにauto_ptrと呼ばれるスマートポインタが搭載されている

ipのライブサイクルが終わると、自動的にdeleteされる autp_ptr 通常のポインタとをauto_ptrに切り替えて使用すると、deleteを使用しなくても、自動でメモリを解放してくれる。 int* ip = new int; *ip = 10; delete ip; ipのライブサイクルが終わると、自動的にdeleteされる auto_ptr<int> ip(new int); *ip = 10;

auto_ptrを別のauto_ptrに代入すると auto_ptr<int> p1(new int); *p1 = 10; auto_ptr<int> p2 = p1; cout << "p2: " << *p2 << endl; cout << "p1: " << *p1 << endl; // コンパイルOK,実行時エラー コンパイルは所有権が移動し、代入元のインスタンスを参照しようとすると実行時エラーになってしまう。

また標準ライブラリのvectorなどのコンテナクラスにも格納することは出来ない auto_ptrは使えない?② また標準ライブラリのvectorなどのコンテナクラスにも格納することは出来ない

Boostライブラリ登場 新しいスマートポインタ Boostとは、C++標準化委員会の多くが参加して作成されたオープンソースライブラリ Boostには新しい4つのスマートポインタが存在する「shared_ptr(weak_ptr), scoped_ptr,intrusive_ptr」 この内shared_ptr(weak_ptr)はC++0x(次期標準C++規格)にそのまま導入される VC-2008(VC9)でVS2008SP1を適用すると、TR1としてshared_ptr(weak_ptr)使用可能

auto_ptrと同じような使い方が可能 shared_ptr① auto_ptrと同じような使い方が可能 shared_ptr<int> pi(new int); *pi = 10;

auto_ptrと違い所有権が無く、他のshared_ptrに代入しても、代入元もそのまま使用できる shared_ptr<int> p1(new int); shared_ptr<int> p2 = p1; cout << "p2: " << *p2 << endl; cout << "p1: " << *p1 << endl;

shared_ptrは参照カウンタを使ってメモリ管理を実現している { shared_ptr<int> p1(new int); // 参照カウント=1 shared_ptr<int> p2 = p1; // 参照カウント=2 shared_ptr<int> p3 = p2; // 参照カウント=3 } // ここで参照カウント=2 } // ここで参照カウント=1 } // ここで参照カウント=0になったのでインスタンスを解放

参照カウンタ方式のメモリ管理を使用した場合、参照先が参照元を参照するような循環参照ではインスタンスを解放できない weak_ptr① 参照カウンタ方式のメモリ管理を使用した場合、参照先が参照元を参照するような循環参照ではインスタンスを解放できない struct UserData2; struct UserData1 { shared_ptr<UserData2> op; }; struct UserData2 { shared_ptr<UserData1> op; int main() { shared_ptr<UserData1> p1(new UserData1()); shared_ptr<UserData2> p2(new UserData2()); p1->op = p2; p2->op = p1; }

weak_ptrは弱参照ポインタで参照カウントを増加させない struct UserData2; struct UserData1 { shared_ptr<UserData2> op; }; struct UserData2 { weak_ptr<UserData1> op; int main() { shared_ptr<UserData1> p1(new UserData1()); shared_ptr<UserData2> p2(new UserData2()); p1->op = p2; p2->op = p1; // p1 の参照カウントは増加しない }

scoped_ptrはauto_ptrやshared_ptrと違い、メモリ管理は行わない その代わり代入は出来ない { scoped_ptr<int> p1(new int); *i = 10; scoped_ptr<int> p2 = p1; // コンパイルエラー }

次期標準C++規格のC++0xには、auto_ptrの代わりにunique_ptrが導入される C++0xの詳しい説明は:わんくま同盟 東京勉強会 #22の「C++0x 言語の未来を語る」by アキラさんをみましょう。

C++03 Boost C++0x auto_ptr unique_ptr shared_ptr weak_ptr scoped_ptr それぞれのスマートポインタ関係 C++03 Boost C++0x auto_ptr unique_ptr (auto_ptrも互換性のために残される) shared_ptr weak_ptr scoped_ptr