C/C++

Posts filed under C/C++

Accelerated C++ 8~12章

Filed in C/C++, prog, , 読書感想文

 今日も今日とて読書の日々です。考えてみれば読書強化月間とか言わなくても本読んでるよなぁ普段から。とか思わないでもないのは内緒です。
 さて、今日の一冊はお馴染みアンドリュー・コーニグ、バーバラ・E・ムー著、Accelerated C++ 効率的なプログラミングのための新しい定跡 8~12章です。
 前回にも言ったとおり、8章からは抽象度の高いプログラムを自分で書く立場に変わります。その手始めとして第8章ではジェネリック関数の書き方を解説しています。
 ついに出ましたテンプレート。長月的にはもう無くてはならない物です。テンプレート大好き。
 この章では、テンプレート関数とイテレータを使って総称的な関数を書いていきます。実質各種イテレータの解説がほとんどです。
 第9章では、ついにクラスが登場します。ここから第12章まででユーザ定義型を定義する為に必要な事を解説していく展開です。
 今までにも実質的に同じ物である構造体は出てきていましたが、メンバ関数などは定義していない所謂POD (Plain Old Data) でした。今回は構造体ではなく、メンバ関数も含めてクラスを定義します。以前、第四章の所で少し書いたように、構造体と共にヘッダに追い出されていた関数群がメンバ関数になる流れです。
 この章の内容は普通にC++の本を読んでいたら当然の如く知っているはずの事ですね。要するにカプセル化に気を使えとかそう言った類の事です。
 第10章では、メモリとデータ構造の詳細に触れていきます。他にはファイルへの入出力も少し扱っています。
 ここでやっとポインタの登場です。ポインタが絡むと一気にややこしくなるのがC/C++なので、こうやってポインタを後回しにするのは良い方法だと思います。C言語ではそうもいきませんが(´・ω・`)
 内容としてはポインタの絡む事をあれこれ、関数ポインタや文字列リテラルなんかにも触れています。また、メモリにまつわるあれこれも解説しています。記憶域クラスに関することやコンストラクト・デストラクトに関する事なんかが主です。
 この章もまともに学習していれば問題ない所でしょう。
 第11章では、抽象データ型を定義します。具体的には vector のクローンを作成する事で、抽象度の高いコンテナ等の書き方を学びます。
 この章のキモはコピー絡みの部分でしょうか。代入演算子やコピーコンストラクタの定義にまつわるトピックスはしっかり理解しましょう。コンテナ型に限らず、値のセマンティクスを持ったクラスの定義に役立つ理論です。
 第12章では、値のセマンティクスを持ったオブジェクトの定義を学びます。値のセマンティクスを持つと言うのは、言い換えればプリミティブ型と互換の動作をするオブジェクトと言う事です。
 この章で気をつけるべきは、変換に関する問題と演算子ですね。これらの定義を誤ると構文は正しいのに意味が間違っていると言う見つかりにくいバグの元になります。この辺りの事はしっかり理解しておきましょう。
 今回読んだ部分は、基本でありながら重要な部分です。文法に関しては割とすぐ覚えられると思いますが、ユーザ定義型を定義する際に気をつけるべき事等、論理的な部分に関しては気が付けば間違っていたと言った事が良く起きる部分です。これらの部分は気をつければコーディングの手間を減らし、誤ると後に手痛いバグとして帰ってくる部分なので、しっかりと理解できるまで何度でも読むべき部分でしょう。
 とか言いつつ長月もそうしなければならない程度のヘボプログラマなんですが(´・ω・`)
 さて、長らく続いた本書のレビューも次で最終回です。次回は13~16章を取り上げます。本書のレビューが終わったらまた何かC++関連書籍のレビューをしたいと思っているのでC++使いの方お楽しみに。では今回はここまで、さようならノシ
 <<6~7章 目次 13~16章>>

Accelerated C++ 6~7章

Filed in C/C++, prog, , 読書感想文

 あおいろ日記豪華三本立て読書感想文フェア第二弾は、アンドリュー・コーニグ、バーバラ・E・ムー著、小林健一郎訳、 Accelerated C++ 効率的なプログラミングのための新しい定跡 6~7章です。
 今回はC++を便利に使う事に注力した前半部分の締めくくりです。8章以降は使うだけではなく、機能を提供する際に特に役立つ機能の解説へと移っていきます。それでも使う事に主眼が置かれている事には変わりませんが。
 まず第6章では、第5章までに学んで来たシーケンシャルコンテナに対して、STLに用意されているアルゴリズムを適用する事を解説しています。後、記憶域クラス指定子が初登場します。意外な事にここまで出てきてなかったんですね。
 この章は、言ってしまえばいくつかのアルゴリズム系関数の使い方を見ていくだけです。しかし、課題を工夫する事でイテレータアダプタやリバースイテレータ等、必要な事は大体網羅しています。
 私見ですが、コンテナやイテレータの扱いには慣れている人でも、意外とイテレータアダプタを知らなかったりする事が多いようです (使う必要が無い事も多いのは確かですが……)。心当たりがある人は本章で慣れておくと良いでしょう。
 第7章では、連想コンテナを扱います。連想コンテナの例題としてはお馴染みのワードカウントや対応表、英文の自動生成の製作を通して主に map の解説を行っています。
 例題のプログラムを見ていると、なにやら懐かしい気持ちになります。大抵の人は上記の様なプログラムで map の勉強をしたのではないでしょうか?
 すでに連想コンテナをバリバリ使ってる人は昔を懐かしみながら復習するのも良いでしょう。
 さて、第7章までで抽象度の高いライブラリを使う事に関しては学べました。次章からは自分が抽象度の高いプログラムを書くにはどうすべきかに注力して展開していきます。しかしOOPらしくなるのは13章まで待たなければならないのがにくいですね。
 ここまでは入門者さんにオススメの部分でした。今までの内容にも初~中級者が学ぶべき事は色々ありましたが、ある程度C++かじった人には次章以降を強くオススメしたいと思います。次章以降は今後二回に分けて書いていきたいと思います。
 <<0~5章 目次 8~12章>>

Accelerated C++ 0~5章

Filed in C/C++, prog, , 読書感想文

 はい、早くも浮気です。OS【第二版】は読むのに気合が要るので疲れます。今日はさらっと流したかったので楽に読める本を。
 今日読んだのはアンドリュー・コーニグ、バーバラ・E・ムー著、小林健一郎訳、Accelerated C++ 効率的なプログラミングのための新しい定跡 0~5章です。全然軽くねぇ……orz
 この本は、C++とSTLを便利に使ってしまおうと言う所から始まる入門書です。文法や規則の説明は必要になってから、とりあえず使ってみようよと言うスタンスで書かれています。以前書いたエントリで長月が言っていたスタンスですね。事実この方法は良いと思いました。
 さて、この本は大まかに0~7章までの前半と8~10章の後半に分かれています。今回は前半の中でも0~5章について書きます。
 まず第0章はC++事始めとしてお決まりの hello, world! から始まります。単純な hello, world! にも実はこれだけの物が詰まってるんだよ? と言った風情で書かれています。この辺りは C/C++ 未経験者以外は読み飛ばしても大丈夫です。
 第1章では、早速 iostream を用いた入出力と string を用いた値の保存を行います。さらに、string のメンバ関数を使って、入力文字列に合わせて自動的にサイズを調整したフレームを表示したりもします。
 コンストラクタやメンバ関数を巧みに使っていて、初見の時になるほどと思わされた覚えがあります。C++経験者でも意外と知らない string の使い方かもしれません。
 第2章では、第1章で書いたプログラムを拡張します。第1章で書いたプログラムでは、フレームとして出力される文字列がそれぞれ string 型の変数としてハードコードされていました。それをフレキシブルな形に書き直すのが第2章の目的です。
 ここまで来てやっとループです。まあここまで来てと言っても20ページ無いんですが。
 残念なのが、コードが余り技巧的ではなくなって見ごたえが無い事です。必要な事に必要なだけ、そして解りやすく書かれているエレガントなコードなんですが、第1章で見たようなああなるほどと言った感動はありませんでした。
 続いて第3章では、たくさんのデータを扱うと言う題の通り、コンテナが登場します。
 これまでに学んで来た入出力やループを使って、生徒の宿題やテストの点数を入力し、学期の成績を計算するプログラムを作り、それを平均点の計算からメディアンを求めるプログラムに拡張すると言う段階を踏んで vector の使い方に繋いでいます。
 ここでのプログラムも何か引っかかる物があります。それが解決されるのが次章です。
 第4章に入ってやっと関数が登場します。前述した違和感の正体がこれです。既にプログラミングを嗜んでいる人間にとっては、長い main 関数が引っかかる訳です。
 第4章では、前章で作成したプログラムを、関数を用いた物に書き直していきます。さらに、複数の生徒の成績を扱う為に、データを構造体によって関連付けたり、ちらっと例外も顔を出します。それと構造体や構造体を利用する関数をヘッダファイルに追い出したりもしてますね。後にクラスの解説へと繋がりそうです (と言うか繋がります)。
 この章では sort や max 等のアルゴリズム系関数も出てきます。長月の私見ですが、どうも長月を含めた中途半端なレベルのC++使いは、STLのコンテナは良く知っていてもアルゴリズムを良く知らない様に思えます。本書を読んでいると、このやり方ならそういう偏りは出来にくいかもなあと思います。
 本日の締め、第5章ではイテレータが解説されます。前章のプログラムに合否判定の機能を加える為に、vector の巡回をすると言った感じです。
 イテレータは vector に特有の物ではありません。本章では、vector の部分削除や挿入に伴うコピーに起因する速度低下を不満として、list への差し替えを行います。
 さらに、イテレータで範囲指定する類の関数も使い始めます。
 なんと言うか、やっとSTLの本領が見えてきたと言った所でしょうか。C++はちょっと触っている人なんかはここら辺り方楽しくなってくるのではないでしょうか。
 上記のレビューにもちょこちょこと書かれていますが、本書は入門書で有りながら、経験者にも有益な本でもあります。文法や機能等に着目した従来の本と違い、問題解決に着目した作りであるため、意外な所で今までもやもやしていた物が解決したりします。
 自分はC++を使っているしそれなりに使えているからと思っている方も一度読んでみては?
 目次 6~7章>>

ぐぐるの頻出クエリを元にエントリを書いてみよう第一回

Filed in C/C++, prog

 ぐぐるからのお客さんの傾向を調べてたら頻出キーワードに「STL」があると判明。なのでSTLに関して何か書いてみようとおもいます。
 STLだけでは広すぎるので、STLと一緒に検索されたキーワードで最も多かった「スマートポインタ」を絡めてみます。
 さて、STLで検索してきてる人は、多分STLがなんであるかはご存知のはずですね。
 STLは標準C++に付属する標準ライブラリの一部で、テンプレートを用いたコンテナやアルゴリズムなんかのライブラリを指します。
 入門書の類などで特によく使われるのstringやvector、iostreamなんかもSTLに含まれるジェネリッククラスですね。
 さて、このSTLにはコンテナ、アルゴリズム、ユーティリティ、イテレータなどが含まれます。
 コンテナはデータ構造、アルゴリズムは言葉の通り、ユーティリティはちょっとした処理をテンプレート化した関数群、イテレータはデータ構造体を巡回する際などに使うポインタの代わりになるものです。
 最後に挙げたイテレータ、これってある意味スマートポインタなんですよね。
 スマートポインタと言えるほどの汎用性は無いんですが、STLコンテナの中を巡回することに関してはまさに「賢いポインタ」として動作してくれます。
 まずC言語での動的配列のイディオム。

    int *ida = (int*)malloc(sizeof(int) * 10);

 があった時、ポインタとポインタ演算を用いてこの配列の中身を頭から順番に設定していくコードは以下のようになります。

    int *ip = ida;
    int i;
    for(i = 0; i < 10; ++ip, ++i){
        /* something() はint型の何らかの値を返する関数 */
        *ip = something();
    }

 これを、C++での動的配列のイディオムで表現すると。

    std::vector<int> ida(10);
    for(std::vector<int>::iterator ip = ida.begin();
         ip != ida.end();
         ++ip){
        // something() はint型の何らかの値を返す関数
        *ip = something();
    }

 ipに対する操作に着目するととても似てますね。イテレータはポインタを模して作られているのです。
 しかしこれだけだとありがたみがわかりませんね。そこでリンクリストに関しても見てみましょう。
 C言語だと、典型的なリンクリストの巡回は以下のようになります。

    typedef struct list_tag{
        int value_;
        struct list_tag *next_;
    } List;
    /* (snip) */
    List *iter;
    for(iter = Data; iter != DataEnd; iter = iter->next_){
        /* something() はint型の引数を受け取る関数 */
        something(iter->value_);
    }

 C++で書いてみましょう。

    std::list<int> Data;
    // (snip)
    for(std::list<int>::iterator iter = Data.begin()
         iter != Data.end();
         ++iter){
        // something() はint型の引数を受け取る関数
        something(*iter);
    }

 iterに着目したとき、C言語版よりも楽になった感じです。なにより、C++版だと、iterに対する操作は本質的にvectorの場合と変わってません。
 ただのポインタの場合、データ構造ごとに違う探索操作をしなければならないところを、実際の動作を隠蔽して統一的な操作で行ってしまうのがイテレータの魅力です。ことコンテナの探索に関しては立派にスマートポインタと言えます。
 しかし、検索で来てる方々は、こういったものではなくて汎用のスマートポインタを探してますよね。
 STLにも一つ、汎用のスマートポインタがあります。auto_ptrがそれです。もちろんデストラクト時にちゃんとdeleteしてくれます。
 auto_ptrは破壊的スマートポインタと呼ばれる方法で実装されたスマートポインタです。あるポインタについて、一つだけ所有権を認めます。
 例えば以下のようにすると、aは0 (NULL) を指し、aの指していた領域をbが指すようになります。

    auto_ptr<int> a(new int(10));
    auto_ptr<int> b(a);
 あるいは
    auto_ptr<int> a(new int(10));
    auto_ptr<int> b;
    b = a;

 ソース側の状態を破壊するので破壊型という訳です。しかしこれなら確かにリークはありません。
 しかしこの方法、割と問題あるんですよね。例えば。

// 参照渡しのつもりでポインタ型引数を受け取って二倍にして引数経由で値を返す関数
void Double(int* ptr){ *ptr *= 2; }
// 生のポインタは怖いからスマートポインタ用にオーバーロード
void Double(auto_ptr<int> ptr){ *ptr *= 2; }
int main(){
    int i = 20;
    auto_ptr<int> ptr(new int(10));
    Double(&i);
    Double(ptr);
    cout << i << ", " << *ptr << endl; // 不正な参照はがし
    return 0;
}

 Double(int*)はうまく動きますが、Double(auto_ptr<int>)はうまく動きません。
 Double(auto_ptr<int>)では、auto_ptr<int>を値渡ししています。なので、実引数はコピーされるのです。auto_ptrではコピーが発生すると、ソース側が破壊されるので、関数本体に入った時点で既に呼び出し側のptrには0が設定されています。なので出力行での参照はがしは不正なメモリアクセスとなります。なので上記のような場合は参照で渡しましょう。
 また、ポインタを保持するコンテナではポインタの代わりにauto_ptrを使おうとすると痛い目に遭うかもしれません。

    vector<auto_ptr<int> > iapv1;
    vector<auto_ptr<int> > iapv2;
    iapv1.push_back(new int(10));
    iapv1.push_back(new int(20));
    iapv2 = iapv1; // ここでコピーが発生。iapv1の保持するポインタが破壊される
    *iapv1[0] = 100; // 既にiapv1[0]はヌルポインタなのでエラー

 正直知らないと気付きません(´・ω・`)
 破壊型という特性故にauto_ptrは使いづらいと言う評価を受けるようです。長月もスマートポインタをご所望の方はBoostのshared_ptrを使ったほうが良いかと思います。
 それでは今回はここまで。また気が向けばやってみます。当日記に出てきたキーワードで、何か知りたいことがある方はぐぐる経由でアクセスしまくるといいかもですよ? であであノシ
 #ちなみに最頻出クエリは「hidew」でした(絶爆) おめでたうw>hidewさん

第一章を読んで (Exceptional C++の場合)

Filed in C/C++, prog, , 読書感想文

 とりあえず第一章を読み終わっての感想。
 読んでみて長月はSTLのコンテナとイテレータに関しては問題ない程度、アルゴリズムがちょっと弱いらしい。と言う事が判った。
 ので、この本、クイズ形式になってるからか、傾向と対策本として使えそう。
 問題集になってる本のいい所はちゃんとやれば自分の弱点がわかる事。そう言った意味ではExceptional C++はちゃんと問題集として機能してそう。
 難易度に関しては、入門者や初級者にはちょっとオススメできない感じ。序文にもある通り、ある程度C++に触れた経験が無いと辛いと思う。
 かといってバリバリに使ってないと無理かと言われるとそれ程でもない。ちゃんと学習してそれなりに自分で何かを作ってれば経験してる事が書いてある様に見える。
 どこかのBBSやMLで相談されていて、解答を読んでなるほどと思っていた事なんかが載っていたので、割と多くの人が悩む所についての解法が書かれている感じ。
 物によってはそう言った場で挙げられた解法よりよさげな事なんかも書かれているので、ある程度「濃ゆい」C++コミュニティに参加してる人なんかは読んでみても良いんじゃないかと思う。
 cppll辺りに参加してる人は一読してみては?

今度はExceptional C++

Filed in C/C++, prog, , 読書感想文

 Exceptional C++が届きますた。
 これで気になってるC++本コンプまで二向聴。
 Exceptional C++を読み終わったらEfficient C++Boost本STL標準講座を買うつもり。
 どれにしよう?(´ワ`)
 その前に目の前の本をちゃんと読め? おっさる通り……orz

ちょっとC++使ってみない?

Filed in C/C++, prog

 最近割とちゃんとした文章書く気が起きなくて日記ばかり書いてた当blogですが。なんだかそろそろ文章短すぎてぐぐる広告様が臍曲げてるのでなんか書いてみようかと思うです。
 とりあえずプログラミングネタ行きますかね。一応うちのメインですから。ネタ取りはcppllの最近の投稿から。
 え~と、とりあえずまず質問。あなたはC++をやってみようと思いますか?
 C言語経験者とかプログラミング経験なしの人って上記の問いに「そう考えた事はあるけど難しいんでしょ?」という答えを返す事があるんですよね。つか最近そういう人多いらしい。
 そこで難しいんじゃないの? と思ってる方々に聞いてみたいのです。本当に難しいですか? って。
 わかんないですよね? まだやってないんですから。
 確かにちょっとかじって挫折した人もいるわけですよ。そういう人達は難しいからやだって言うんでしょうね。
 やっぱり聞いてみたいわけですよ。本当に難しいですか? って。
 まぁそんなこと言っておきながら長月も難しいと思ってるんです。けどね、使えないほどじゃないでしょ?
 使い切れないけど使える部分だけ使っても十分じゃないですか?
 cppllでも投稿されてたんですけど、C++のC言語部分とC++の便利な標準ライブラリ使うだけでずいぶん楽なんですよね。C言語より。
 正直文字列操作のためにmallocとかfreeとかreallocとかで頑張ってダングリングポインタに悩むの馬鹿らしいです。string使いましょ。
 ちょっとした事のために配列使いたいけど確保すべき量が決まってないからってmallocとかfreeとかreallocとかで頑張ってメモリリークに悩むとかやってられません。vector使おうよ。
 STLには他にもリストとかマップとかあってずいぶん楽。だって自分で作るの面倒でしょ?
 んで、自分で頑張って作ってもね。大抵ひとつの型にしか使えないんです。C言語感覚だとね。
 正直汎用性のためとか言ってvoid*とキャストの乱舞とかいやでしょ?
 C++ならテンプレートでそれ解決するんですよ。良いね、テンプレート。色んな意味で楽。
 バイナリサーチとか作ったことあります? クイックソートとか作ってみたことある人多いですよね? データ構造の中から特定の値を見つける関数とか作った事あるんじゃないですか?
 その辺りそう難しいこともない、入門書の類にも書いてありますしね。でもね、いちいちそのときそのとき作りたくはないですよね。STLにはその辺りもありますよ? 標準コンテナと組み合わせて楽チン楽チンですね。
 C言語ってポインタ怖いですよね。やろうと思えばWindowsのハンドル型みたいな似非スマートポインタも作れるけど面倒ですよね? 約束事も増えますし。
 でもC++ならスマートポインタありますよ? 標準ライブラリにもauto_ptrがあるし、Boost使えばもっと賢いのあります。凝ったやつならyaneSDK3rdとかLokiなんかにもありますね。ちょっとしたものなら自分で作ってもそんなに手間掛からないですし。
 C++の機能ってそれぞれひとつだけ見たらそんなに難しくないと思うんです。でもイディオムとして色々組み合わせる物だって言われるから難しい。
 じゃあもう難しいのは他人任せで行きましょう。C++って出来合いのライブラリが優秀なの多いですから。
 自分の手に負えない物使わなくても良いと思うんですよ。使いたくなってから頑張って考えてみれば良いんじゃないかな? やる気があるならなんとかなるでしょ?
 てな訳で食わず嫌いだったり食ってみた所が悪くて嫌いな方々。ちょっとC++使ってみませんか?
 お勧め書籍:Accelerated C++

Modern C++ Design5章辺りで訳わかんなくなってきた

Filed in C/C++, prog

 ので2~3章にトラックバック中……orz
 タイプリストがちゃんと理解できないorz

う~ん……

Filed in C/C++, prog, , 読書感想文

 Modern C++ Design読んでて思ったこと。
 確かに斬新、トリッキーで解りにくいところはあるけど凄いのは凄い。でもちょっとやりすぎじゃないですか?
 なんかそこまでするの?(´Д`;) と思うところがいくつか。
 タイプリストとか便利そうだけど、コンパイルタイムはともかくランタイムは速そうだけどそこまでやりますか? って感じ。
 後を読んで必須だと思えたとしても、却ってLoki自体どうなの? と思うことになるかもしれなさげなトリッキーさ(´・ω・`)
 なんか2chとかで割とえらい言われ様だった理由が理解できた(´・ω・`)

経験不足を痛感(´・ω・`)

Filed in C/C++, prog, , 読書感想文

 Modern C++ Design手強し(´・ω・`)
 テンプレートはユーザとしては慣れてるけど実装者としては慣れてないので宇宙語に見える個所がちらほら出てくる(´・ω・`)
 まだ大して難しいところには入ってないはずなのにもうこんな状況で大丈夫ですか?>俺
 #それでも仕事の休憩時に読んでる中学レベルの英文法書よりは理解できる辺り何かを間違えてる……orz


Warning: sprintf() [function.sprintf]: Too few arguments in /home/users/2/lolipop.jp-dp07042166/web/wordpress/wp-includes/widgets.php on line 1042
Oenology Post Formats
Click to view/hide

Warning: sprintf() [function.sprintf]: Too few arguments in /home/users/2/lolipop.jp-dp07042166/web/wordpress/wp-includes/widgets.php on line 1042
Posts Calendar
Click to view/hide
2017年11月
« 12月    
 1234
567891011
12131415161718
19202122232425
2627282930  

Warning: sprintf() [function.sprintf]: Too few arguments in /home/users/2/lolipop.jp-dp07042166/web/wordpress/wp-includes/widgets.php on line 1042
アーカイブ
Click to view/hide

Warning: sprintf() [function.sprintf]: Too few arguments in /home/users/2/lolipop.jp-dp07042166/web/wordpress/wp-includes/widgets.php on line 1042
最近の投稿
Click to view/hide