• この PowerPoint ファイルには、「ノート」 セクションにセッションの講師が話し ている内容を書き起こしたもの (トランスクリプト) を入力しています。 • ノートを参照するには、PowerPoint の表示モードを [標準] または [ノート] に設定 してください。[標準] の場合は、スライド表示ウィンドウの下 (ノート ペイン) に 表示されます。 • ノート表示モードで見た際にノートが 1 ページに収まりきらない場合は、スライ ドを複製して複数ページにわたってノートを入力しています。そのため、オリジ ナルの英語版ファイルと比較して、スライド番号やスライドの枚数が異なる場合 があります。(本スライドが追加されている時点で、英語版とは枚数が異なります) • ノートを印刷するには、[印刷プレビュー] または [印刷] 画面において、[印刷対象] を [ノート] に指定してください。 • 本プレゼンテーション (以下、本書) で提供されている情報は、本書が 発表された時点における Microsoft の見解を述べたものです。市場 ニーズの変化に対応する必要があるため、本書は記載された内容の実 現に関する Microsoft の確約とはみなされないものとします。また本 書に記載された情報の正確さについて、保証するものではありません。 • 本書は情報の提供のみを目的としており、明示または黙示に関わらず、 本書について Microsoft はいかなる保証をするものでもありません。 • 本書に記載されている機能名や用語の日本語訳は、あくまでも暫定的 なものであり、将来変更される可能性があります。 ロードマップ このセッションの動機と範囲 最新の C++: クリーン、安全、高速 モジュール間の接続について: ABI セーフ、他言語 まとめ 動機と目的 開発者たちの間で C++ への 回帰が広がる プログラミング経験のある方 C++ の変更点に関する知識が ある方 最新の C++ の洗練された コーディング方法を知らない方 最新の C++ による、 クリーンで、安全で、高速な コーディング方法を説明 性能: あらゆる規模で稼働 – オンチップ、モバイル、 デスクトップ、データセンター サイズ: プロセッサ リソースの制限 – デスクトップ、モバイル エクスペリエンス: 小型のハードウェアで 高度なエクスペリエンス を実現 常識を打ち破るには、 あらゆるサイクルが 重要に C++ の価値に対する考え方 C++ の価値提案である効率的な抽象化を実現 強力な抽象化: タイプセーフなオブジェクト指向と汎用コードによる強力な モデル化、制御性も効率性も犠牲にしない コードとメモリの完全制御: 実行したい処理を常に表現可能 メモリとデータのレイアウトを常に厳密に制御可能 従量課金のような効率性: 強制的なオーバーヘッドがなく、必要な分だけ作業 コストが発生 「Facebook では『合理的に記述された C++ コードは高速である』と認識 されており、PHP と Java コードの最適化に多大な努力が費やされたことを 物語っています。C++ は他言語と比べて記述が複雑ですが、 効率的なコードを書くのはずっと簡単です」– Andrei Alexandrescu ロードマップ このセッションの動機と範囲 最新の C++: クリーン、安全、高速 モジュール間の接続について: ABI セーフ、他言語 まとめ 変更点: 概要 auto による型の省略 T* shared_ptr<T> new make_shared 以前 現在 circle* p = new circle( 42 ); auto p = make_shared<circle>( 42 ); vector<shape*> vw = load_shapes(); vector<shared_ptr<shape>> vw = load_shapes(); for( vector<circle*>::iterator i = vw.begin(); i != vw.end(); ++i ) { if( *i && **i == *p ) cout << **i << “ is a match\n”; } for_each( begin(vw), end(vw), [&]( shared_ptr<circle>& s ) { if( s && *s == *p ) cout << *s << “ is a match\n”; } ); for/while/do std::アルゴリズム [&] ラムダ関数 for( vector<circle*>::iterator i = vw.begin(); i != vw.end(); ++i ) { delete *i; 非例外安全 } delete p; try/catch、__try/__finally がない “delete” は不要 有効期間の自動管理 例外安全 変更点: 概要 (続き) auto による型の省略 T* shared_ptr<T> new make_shared 以前 現在 circle* p = new circle( 42 ); auto p = make_shared<circle>( 42 ); vector<shape*> vw = load_shapes(); vector<shared_ptr<shape>> vw = load_shapes(); for( vector<circle*>::iterator i = vw.begin(); i != vw.end(); ++i ) { if( *i && **i == *p ) cout << **i << “ is a match\n”; } for_each( begin(vw), end(vw), [&]( shared_ptr<circle>& s ) { if( s && *s == *p ) cout << *s << “ is a match\n”; } ); for/while/do std::アルゴリズム [&] ラムダ関数 for( vector<circle*>::iterator i = vw.begin(); i != vw.end(); ++i ) { delete *i; 非例外安全 } delete p; try/catch、__try/__finally がない “delete” は不要 有効期間の自動管理 例外安全 素晴らしいものは、変わらない: 自動有効期間 = 効率 + 例外安全 class widget { private: gadget g; public: void draw(); }; 有効期間は自動的に 格納先のオブジェクトに 結び付けられる リークなし、例外安全 void f() { widget w; ::: w.draw(); ::: } 有効期間は自動的に スコープに結び付けられる w を生成 (gadget メンバーの w.g も含む) w と w.g を自動的に 破棄/解放 自動的に例外安全 “finally { w.dispose(); w.g.dispose(); }” ヒープの有効期間: 標準スマート ポインター class gadget; 共有 自動有効期間管理に よって gadget を所有 class widget { リークなし、例外安全 private: shared_ptr<gadget> g; }; class gadget { private: weak_ptr<widget> w; }; 参照カウントを 行いたくない場合は weak_ptr を使用 node が子要素を所有 リークなし、例外安全 class node { vector<unique_ptr<node>> children; node* parent; ::: node は親を保持 public: node( node* parent_) : parent(parent_) { children.push_back( new node(…) ); ::: } “new” はそれを所有する }; パフォーマンスの最適化が必要なとき、所有する * や delete をカプセル化して使用することを検討 (隠しオブジェクトなど) 例: 独自の低レベル データ構造を記述 単有 別のオブジェクト (通常は unique_ptr) を 直ちに初期化 ヒープの有効期間: 標準スマート ポインター (続き) class gadget; 共有 自動有効期間管理に よって gadget を所有 class widget { リークなし、例外安全 private: shared_ptr<gadget> g; }; class gadget { private: weak_ptr<widget> w; }; 参照カウントを 行いたくない場合は weak_ptr を使用 node が子要素を所有 リークなし、例外安全 class node { vector<unique_ptr<node>> children; node* parent; ::: node は親を保持 public: node( node* parent_) : parent(parent_) { children.push_back( new node(…) ); ::: } “new” はそれを所有する }; パフォーマンスの最適化が必要なとき、所有する * や delete をカプセル化して使用することを検討 (隠しオブジェクトなど) 例: 独自の低レベル データ構造を記述 単有 別のオブジェクト (通常は unique_ptr) を 直ちに初期化 「C++ はガベージ コレクションに最も適した言語だ。 その用があまりないのだから」 — Bjarne Stroustrup コンテナー vector<string> v; v.push_back( “Geddy Lee” ); 既定のコンテナー: ベクター コンパクトで効率的: キャッシュや プリフェッチャーに対応 array<string,50> a; 固定サイズ ベクター: 配列 コンパクトで効率的: キャッシュや プリフェッチャーに対応 ディクショナリ: map (ツリー) または unordered_map (ハッシュ) map<string, string> phone; phone[“Alex Lifeson”] = “+1 (416) 555-1212”; multimap<string, string> phone; phone[“Neil Peart”] = “+1 (416) 555-1212”; phone[“Neil Peart”] = “+1 (905) 555-1234”; unordered_map<string, string> phone; phone[“Alex Lifeson”] = “+1 (416) 555-1212”; unordered_multimap<string, string> phone; phone[“Neil Peart”] = “+1 (416) 555-1212”; phone[“Neil Peart”] = “+1 (905) 555-1234”; コンテナー (続き) vector<string> v; v.push_back( “Geddy Lee” ); 既定のコンテナー: ベクター コンパクトで効率的: キャッシュや プリフェッチャーに対応 array<string,50> a; 固定サイズ ベクター: 配列 コンパクトで効率的: キャッシュや プリフェッチャーに対応 ディクショナリ: map (ツリー) または unordered_map (ハッシュ) map<string, string> phone; phone[“Alex Lifeson”] = “+1 (416) 555-1212”; multimap<string, string> phone; phone[“Neil Peart”] = “+1 (416) 555-1212”; phone[“Neil Peart”] = “+1 (905) 555-1234”; unordered_map<string, string> phone; phone[“Alex Lifeson”] = “+1 (416) 555-1212”; unordered_multimap<string, string> phone; phone[“Neil Peart”] = “+1 (416) 555-1212”; phone[“Neil Peart”] = “+1 (905) 555-1234”; ループ処理 for/while/do std::アルゴリズム [&] ラムダ関数 以前 現在 for( auto i = v.begin(); i != v.end(); ++i ) { ::: ::: 任意長のラムダ本体。 ::: ループ本体を } ラムダの中に配置 for_each( begin(v), end(v), []( string& s ) { ::: for_each で各要素にアクセス ::: ::: } ); auto i = v.begin(); for( ; i != v.end(); ++i ) { if (*i > x && *i < y) break; } auto i = find_if( begin(v), end(v), [=](int i) { return i > x && i < y; } ); find_if で一致する要素を検索 非メンバーの begin()/end() を使用 アルゴリズム 既定で以下を使用: for_each: 既定のトラサーバル アルゴリズム not-in-place セマンティクスでは transform を使用 find_if: 既定の検索アルゴリズム sort、lower_bound など: 既定のソートおよび検索機能 比較演算子の記述: 厳格な < を使用。名前付きラムダを使用 auto comp = []( const widget& w1, const widget& w2 ) { return w1.weight() < w2.weight(); } sort( v.begin(), v.end(), comp ); auto i = lower_bound( v.begin(), v.end(), comp ); 値型と参照型 基底クラスと仮想関数 が重要 “コピー可能な” 値型 (既定) “ポリモーフィック” 参照型 class point { int x; int y; public: ::: }; class shape : boost::noncopyable { public: 明示的にコピーを無効化 virtual draw(); ::: }; 無効化は継承される メモリとレイアウトの制御 が重要 class circle : shape { public: virtual draw() override; ::: }; 明示的な オーバーライド制御 値型と参照型 (続き) 基底クラスと仮想関数 が重要 “コピー可能な” 値型 (既定) “ポリモーフィック” 参照型 class point { int x; int y; public: ::: }; class shape : boost::noncopyable { public: 明示的にコピーを無効化 virtual draw(); ::: }; 無効化は継承される メモリとレイアウトの制御 が重要 class circle : shape { public: virtual draw() override; ::: }; 明示的な オーバーライド制御 値型とムーブの効率性 set<widget> load_huge_data() { set<widget> ret; // … データを読み込み、ret に設定 … return ret; } widgets = load_huge_data(); 効率的、ディープ コピー は行わない “ヒープ割り当てと ポインター戻し” は不要 vector<string> v = IfIHadAMillionStrings(); v.insert( begin(v)+v.size()/2, “tom” ); v.insert( begin(v)+v.size()/2, “richard” ); v.insert( begin(v)+v.size()/2, “harry” ); 効率的、ディープ コピーは行わない (150 万 ptr/len 回の代入) HugeMatrix operator+( const HugeMatrix&, const HugeMatrix& ); hm3 = hm1+hm2; 効率的、余分なコピーは行わない 値型とムーブの効率性 (続き) set<widget> load_huge_data() { set<widget> ret; // … データを読み込み、ret に設定 … return ret; } widgets = load_huge_data(); 効率的、ディープ コピー は行わない “ヒープ割り当てと ポインター戻し” は不要 vector<string> v = IfIHadAMillionStrings(); v.insert( begin(v)+v.size()/2, “tom” ); v.insert( begin(v)+v.size()/2, “richard” ); v.insert( begin(v)+v.size()/2, “harry” ); 効率的、ディープ コピーは行わない (150 万 ptr/len 回の代入) HugeMatrix operator+( const HugeMatrix&, const HugeMatrix& ); hm3 = hm1+hm2; 効率的、余分なコピーは行わない 適切な値型でムーブを有効にする class my_class { unique_ptr<BigHugeData> data; public: my_class( my_class&& other ) : data( move( other.data ) ) { } my_class& operator=( my_class&& other ) { data = move( other.data ); } ムーブ コンストラクター ムーブ代入演算子 ::: void method() { if( !data ) throw “moved-from object”; ::: チェック (必要な場合) } }; ? ムーブ: ディープ コピーより コピー 処理が軽ければムーブを有効化 ムーブ / コピー: 一部の 非値型は ムーブのみ対応。例: unique_ptr ロードマップ このセッションの動機と範囲 最新の C++: クリーン、安全、高速 モジュール間の接続について: ABI セーフ、他言語 まとめ Pimpl によるコンパイル時のカプセル化 (C++ C++) Pimpl イディオムを賢く活用して private メンバーを隠ぺいする class my_class { // … public および protected メンバーはここで宣言 … private: class impl; unique_ptr<impl> pimpl; // 不透明な型はこちら }; class my_class::impl { // private で定義 // … private のデータおよび関数: // 呼び出し元を再コンパイルせずに変更可能 … }; my_class::my_class() : pimpl( new impl ) { /* … impl 値を設定 …*/ } カスケードの再構築とオブジェクト レイアウトの脆弱性を回避 (推移的な) 使用頻度の高い型の場合に最も適切 my_class.h my_class.cpp ABI では十分に移植性のある型と規約を使用 (C++ * ) 移植性のある型 = C 組み込み型 (* を含む) および構造体 クラス型を使用できるのは、呼び出し元と呼び出し先がレイアウトや呼び出し 規約などに合意している場合に限る = 同一のコンパイラ + 設定によるコンパイル 呼び出し元が別のコンパイラ/言語でコンパイルされている場合: 特定の呼び出し規約で “extern C” API に変換 class widget { widget(); ~widget(); double method( int, gadget& ); extern “C” { // 明示的な “this” を関数で使用 struct widget; // 不透明な型を使用 (前方宣言のみ) widget* STDCALL widget_create(); // ctor “this” を作成 void STDCALL widget_destroy( widget* ); // dtor “this” を破棄 double STDCALL widget_method( widget*, int, gadget* ); //“this” を使用 }; } WinRT の型: クロス言語での使用 (C++ JS/.NET ) C/C++ の 外部サーフェス WinRT の 外部サーフェス “C” handle スタイル、 C++ Pimpl スタイルを使用 WinRT の呼び出し元/ 呼び出し先 モジュールの 内部処理 C++ で作成 C++ と WinRT 型の種類を明示可能: 値型、参照型、インターフェイス 標準 C++: 移植性と効率性に優れた型 C++/CX: WinRT と ABI セーフな型 class point { int x; int y; }; class drawable : boost::noncopyable { public: virtual void draw() = 0; }; class shape : public drawable { … }; class circle : public shape { … }; value class Point { int x; int y; }; interface class IDrawable { virtual void Draw(); }; ref class Shape : IDrawable { … }; ref class Circle : Shape { … }; ::: ::: auto p = make_shared<circle>(); shared_ptr<drawable> p2 = p; p2->draw(); auto p = ref new Circle(); IDrawable^ p2 = p; p2->draw(); 型は ABI セーフかつ WinRT とのクロス言語 2 つの主な概念: ^ と ref new ロードマップ このセッションの動機と範囲 最新の C++: クリーン、安全、高速 モジュール間の接続について: ABI セーフ、他言語 まとめ C++ への回帰 C++ が再び業界の注目を集める マイクロソフトは C++ へのコミットメントを刷新: Windows 8 向けの新しいプログラミング モデル CPU と GPU のパワーをフル活用 Windows 8 のハードウェア機能をフル活用 ARM 対応 Visual C++: Windows のパワーとパフォーマンスを備えたツール 関連セッション CHANNEL 9 のオンライン セッション • TOOL-100T: Improving software quality using Visual • Bringing Existing C++ Code into Metro Style Apps • TOOL-479T: A lap around Visual Studio 11 Express • Under the Covers with C++ for Metro style Apps • TOOL-532T: Using the Windows Runtime from C++ • Building Metro style apps with HTML5 and Studio 11 C++ Code Analysis for Metro style apps using C++ • TOOL-761T: A lap around DirectX game development tools • TOOL-802T: Taming GPU compute with C++ AMP • TOOL-845T: Tips and tricks for developing Metro style apps using C++ Ale Contenti Deon Brewis Compiled Code Raman Sharma • Why C++: C++ Renaissance Herb Sutter Q&A http://forums.dev.windows.com http://bldw.in/SessionFeedback
© Copyright 2024 ExpyDoc