サクサク読めて、アプリ限定の機能も多数!
トップへ戻る
今年の「#文学」
www7b.biglobe.ne.jp/~robe
前回に続いて、今回もC++のキャストについて話します。C言語のキャストにはない特別な機能を持ったキャストです。 では、今回の要点です。 dynamic_cast を使えば継承関係をチェックしてくれる。 不当なキャストの時は NULL を返す。 dynamic_cast を利用するには、ランタイムタイプ情報が必要。 では、いってみましょう。 先ずは、前回の CFile と CBinaryFile と CTextFile の話を思いだしてみましょう。CBinaryFile クラスのオブジェクトのアドレスを一旦 CFile* に渡したものを CTextFile* にキャストすると困るというものでした。(ここで、CBinaryFile と CTextFile は CFile の派生クラスです。これらは第2部の継承の話で作ったあのクラスそのものです。) というのも、CBinaryFile ではバイナ
第9章でオブジェクトを値渡しするプログラムをやりました。誰かここに int 型の値を入れた人はいませんか? 今回はそんな話です。 今回の要点です。 値渡しする引数では、コピーコンストラクタ以外のコンストラクタも呼ばれる。 値渡しでコンストラクタを呼ばれないようにするには、コンストラクタの宣言に explicit をつける。 では、いってみましょう。 早速、次のプログラムを見て下さい。 // Copy1b.cpp #include <iostream.h> #include "IntArray.h" void Disp(CIntArray array) { int i; for(i = 0; i < array.NumOf(); i++) cout << array.Get(i) << ' '; cout << endl; } int main() { CIntArray arrayAtoZ
ゲームなどを作っていると、乱数が欲しいなと思うことがよくあります。しかし、乱数というのはコンピュータにとっては苦手な分野です。でも、なんとか乱数を使うことができます。今回はその方法を教えましょう。 では、今回の要点です。 乱数は rand で取得できる。 乱数は srand で初期化できる。 初期化には時間を利用すると良い。 では、いってみましょう。 さて、サイコロ2つを振ってその合計を求めたいと思います。そのためには、サイコロの動作を真似する必要があります。 これには、乱数を用いればいいですね。乱数とは、一言で言うと「無茶苦茶な値」です。例えば、まさにサイコロを適当に振ったときの目の値は乱数になりますね。 この乱数は rand という関数で得ることができます。0から RAND_MAX までの範囲の乱数値を得ることができます(RAND_MAX はマクロです)。必要なヘッダファイルは std
今回は新しいクラスを作ります。が、特に意味のないクラスです。ちょっと説明的になってしまいますが、勘弁して下さい(汗)。 なお、数章後にまた CIntArray を改造するので、ソースは残しておくことをおすすめします。 では、今回の要点です。 静的メンバ変数は実体を別に宣言する必要がある。 静的メンバ変数はどれだけクラスを作っても共有される。 では、いってみましょう。 今回はメンバ変数に static を付けてみます。これがどんな意味を持つか、それを確認していきたいと思います。 今回使うクラスはこんな感じです。 // SMember1.cpp #include <iostream.h> class CNum { private: int m_num; public: CNum(int num){ m_num = num; } void Disp() { cout << m_num << en
今回からは継承から離れ、普通のクラスに関する話をやっていきたいと思います。先ずは、初期化のタイミングがさっぱり分からないメンバの初期化方法について話したいと思います。 それでは、今回の要点です。 const 定数メンバには代入できない。 コンストラクタの後に : <変数名>(<初期値>) と書けば、その変数を「初期化」できる。 オブジェクトをメンバにとっている場合も、同様にしてコンストラクタが呼べる。 では、いってみましょう。 今回から、CIntArray に話を戻します。 IntArray.h と IntArray.cpp はきちんと残していますか? 残していない人もいると思うので、こちらに掲載しておきます。 さて、CIntArray のメンバ m_nNumOf は配列の要素数でした。よく見ると、このメンバはコンストラクタでしか値が代入されていません。 こういう値があると const を
今回はコンストラクタについてのお話です。継承した場合、コンストラクタはどう呼ばれるのでしょうか? それでは、今回の要点です。 基底クラスから順にコンストラクタが呼ばれる。 基底クラスの引数付きコンストラクタを呼ぶには、 実装時に : <基底クラス名>(<実引数リスト>) と書く。 では、いってみましょう。 前回までのプログラムで不思議に思ったことはありませんでしたか? CTextFile にはコンストラクタがありませんでした。 こういう場合は特に何もしないデフォルトコンストラクタが自動的に作られるのですが、m_pfile, m_bCopy メンバの初期化はどうなるんでしょうね? 簡単なプログラムを作って、継承した場合にコンストラクタがどう呼ばれるかを確かめてみましょう。併せて、デストラクタについても確かめてみます。 // Inherit1.cpp #include <iostream.h>
// Include1.cpp #include <iostream.h> #include "Include1.h" int main() { Hello(); return 0; } void Hello() { cout << "やぁ、こんちは。" << endl; return 0; } // Include1.cpp #include <iostream.h> // Include1.h void Hello(); int main() { Hello(); return 0; } void Hello() { cout << "やぁ、こんちは。" << endl; return 0; } 関数のプロトタイプだけを Include1.h というファイルに分けて書きました。そして、Include1.cpp に #include "Include1.h" と書き、このファイルを取り込
「メンバ変数はできる限りメンバ関数を通して使う」ように奨励しました。ですが、「メンバ変数の値を返すだけ」「メンバ変数の値を設定するだけ」という関数を作っても、その関数を呼ぶ時間が無駄な気がします。今回は、こういうときにピッタリな「アノ」機能が再登場します。 それでは、今回の要点です。 inline をつけるとメンバ関数もインライン関数になる。 クラスの宣言の中で実装してもインライン関数になる。 インライン関数の実装はヘッダファイルで行う。 では、いってみましょう。 メンバ変数はメンバ関数を通して使うのが普通です。例えば、前々回の m_pnum というのもそうしていますね。こうすれば、変な要素を使われることがない上に、m_pnum の値を変えられてしまうこともありません。 もちろん、必ずそうしなくてはならないということではありませんが、そうした方がいい場合がほとんどというのが実際です。 とい
今回は、前回の qsort を使って構造体配列をソートをしてみます。その時、とっても困ることが起きるのです。 では、今回の要点です。 構造体の配列を直接ソートすると遅い。 要素へのポインタ配列を作り、そのポインタをソートするとよい。 では、いってみましょう。 前回と違い、今回は構造体のソートをします。その構造体は次のようなものにします。 struct SMember // 会員データ { int nID; // ID int nYear; // 誕生年 int nMonth; // 誕生月 int nDay; // 誕生日 }; データは乱数で20個作って、生年月日をもとに昇順でソートしたいと思います。 それでは、早速プログラムを作ってみましょう。 // Sort7.cpp #include <stdio.h> #include <stdlib.h> #define numof(array
前回のプログラム。実はクラスを使ってる部分に const がありませんでした。そして const をつけると...エラーが出ます。今回はクラスにおいての const の扱いについてのお話です。 では、今回の要点です。 const オブジェクトは const メンバ関数しか呼べない。 const メンバ関数では mutable メンバ変数しか変更できない。 では、いってみましょう。 では、前回までのプログラムの一部分を見てみましょう。 CIntArray::CIntArray(CIntArray& rother) { ...略... } void Disp(CIntArray array) { ...略... } いつもなら、これらの引数の型には const をつけているところです(const を忘れたという人は第1部第41章,第42章を参照)。なぜなら、rother も array も、関
構造体のサイズを確認してみたことはありますか? 構造体をファイルに保存したことはありますか? やけにサイズが大きかったり、ゴミが保存されたりはしませんでしたか? 今回は、そういうことがなぜ起こるのかについてのお話です。 では、今回の要点です。 構造体のメンバはぎっちり詰まっていないことがある。 #pragma pack でアラインメントを変更できる。 メンバ変数の構造体の先頭からの位置は offsetof マクロで取得できる。 では、いってみましょう。 次のような構造体を考えてみましょう。 strcut SPerson { char szName[21]; // 名前 int nAge; // 年齢 char nBirthmonth; // 誕生月 char fSex; // 性別 }; さて、問題です。この構造体のサイズはいくらになるでしょうか? 先ず、szName のサイズは21バイト
1つのソースファイルで全てのプログラムを書くと、大きなプログラムになると大変なことになります。分業で開発するときにも、ファイルが1つだけというのは不便です。今回はソースファイルの分割方法...の前に、その時に必要なリンケージという概念について話したいと思います。 では、今回の要点です。 ファイルを越えて利用できるかどうかをリンケージと呼ぶ。 そのファイルの外部でも利用できるものは外部リンケージを、そのファイルの内部でしか利用できないものは内部リンケージを持つと言う。 変数宣言に extern をつけると別ファイルの外部リンケージのグローバル変数が扱える。 関数のプロトタイプを書けば別ファイルの外部リンケージの関数が扱える。 static をつければ内部リンケージになる。 では、いってみましょう。 グローバル変数と関数は、ファイルを越えて利用することができます。しかし、ファイルを越えて利用さ
いよいよ始まります第4部。先ず第1章では標準ライブラリについてざっと話していこうと思います。みんなでこのライブラリを使い倒してしまいましょう! それでは、今回の要点です。 どんなコンパイラにでもついてくることが推奨されている標準ライブラリなるものが存在する。 標準ライブラリ内の名前は std 名前空間に属している。 stdio.h 等C言語のヘッダファイルは cstdio のような名前で提供される。 iostream.h 等古いC++のヘッダファイルは iostream のような名前で提供される。 では、いってみましょう。 さて、皆さんはヘッダファイルを一切インクルードせずにプログラムを組んでみたことはありますか? もちろんヘッダファイルの中身を抜き出して書き込んでもダメです。 え? それじゃぁ文字も表示できないじゃないかって? それは全くその通りで、C++で iostream.h などの
今回はキャストのお話です。「何を今さら」と思うかも知れませんが、実はそうでもないのです...。 では、今回の要点です。 C言語のキャストは3種類に分類できる。 static_cast は静的な普通の型変換を行うキャスト。 reinterpret_cast はポインタの関係する強引な型変換を行うキャスト。 const_cast はポインタの const を外すキャスト。 では、いってみましょう。 キャストについては第1部第21章で話しましたが、実はこれはC言語のキャストです。C++から導入されたキャストというものも存在します。今回はそのお話です。 今まで、キャストは何も考えず (int) や (void*) としてきました。しかし、C++ではそのキャストを3種類に分類しています。どう分類しているかは、順を追って話していきましょう。 先ずは1つ目は「静的な普通の型変換」です。次のプログラムを見
マクロは非常に便利ですが、使い方を心得ておかなければマクロ特有のバグを誘発する危険があります。それを防ぐためには、マクロのことをよく知っておく必要があるでしょう。 今回は、先ずマクロのいけない書き方を書いて、それから正しい表記について説明するという形式を取ってみたいと思います。 今回の要点はこんなところです。 マクロ名と差し込むテキストとを分けるものは「空白」。 カッコの終わりもマクロ名と差し込むテキストの境界になる。 演算子の優先順位を無視した書き方は厳禁。 改行したい時は行の終わりに \ を付ける。 では、いってみましょう。 早速1個目を見てみましょう。 #define FUNC (name) void name(int x, int y) うわぁ、これはだめですね。だめですが、見つけやすいバグですね。コンパイルエラーになりますから。 マクロ名と差し込むテキストとを分けるものは「空白」
所用で分散コンピューティングに手を出す可能性が出てきたので、今のうちに勉強しておこうと思って LAM という MPI(メッセージ通信インタフェイス)のライブラリをインストールしてみました。(非職業)プログラマの血が騒ぐような騒がないような微妙なところですが(何じゃそりゃ)、やはり何となく楽しみなところではあります(結局楽しみなんかい!)。 ということで、今回のプログラマの友のテーマは「分散コンピューティング」です。計算機科学などで使われるこの技術は、巨大な計算を沢山のコンピュータを使って並列計算しよう、というものです。そこではプログラム上、ハード上の様々な問題がありますが、それらにできるだけ無駄な労力を割かないようにするためにはやはり専用のライブラリが必要だと思います。 今回私が使ったのは上記にある MPI という規格に沿った LAM(Local Area Multicomputer)とい
前回の new オーバーロードを利用すると、面白いことができます。また、実はVC++の環境でも new が失敗したときに例外を投げるようにできます。今回はそういうお話です。 では、今回の要点です。 引数付き new を使って、後からコンストラクタを呼ぶことができる。 new の投げる例外の型は std::bad_alloc 。 _set_new_handler を使えばVC++でも例外を投げることができる。 では、いってみましょう。 突然ですが、コンストラクタやデストラクタを直接呼んでみたことのある人はいるでしょうか? やったことのある人も、やっとことのない人も、とりあえず次のプログラムをコンパイルしてみましょう。 // New5.cpp #include <iostream.h> class CTest { public: CTest(){ cout << "CTest" << endl
こんなの作ってみた。どうぞよろしく。 DOS窓で動くプログラムを作って説明しています。言語の基本をしっかりと理解しましょう。 なんか凄い紹介されていますが、講座が本になりました。 書かれている通り、かなり内容を変更しています。講座にはいくつかの間違いが含まれていますが、本では可能な限り直してあります。説明の足りない部分、分かりづらい部分、日本語のおかしい部分なども加筆修正してあります。根本的に内容を変更している部分も多いですし(特にクラス関連)、新規に追加した内容もあります。図も大幅に増強して、かなり内容が変わっていると感じるかと思います。 ページ数は 946 ページとかなりの分量(そして分厚さ)になりましたが、途中まで読んだだけでも(エレガントではないまでも)プログラムを組む事ができるように作ってあるので、途中で挫折してもいっかと気楽な気持ちでお読み下さい。 本もWebと同様に各節の冒頭
何年か前に単純な興味からコンパイラ(A.V.エイホ、R.セシィ、J.D.ウルマン著、原田賢一訳。麻宮騎亜の漫画の方ではない)という本を読んだことがあるのですが、途中から yacc, lex といった解析プログラム作成プログラムの話になって「プログラム持っとらんけん実践できんやないの」とやるせなくなったことがあります。 で、Cygwin に yacc, lex の上位バージョンである bison, flex が入ってることが分かったので、その bison を使ってみることにしました。折角タダで用意してくれているので、info bison を読んでやってみることにしました。 今回のプログラマの友はその覚書のようなものです。bison を使おうと思ってるけど尻込みしている人の参考資料にでもなれば幸いです。 (註:用語には無頓着なので不正確なことがあります) bison とは? 構文解析の基本知識
前回 bison を使ったので、今回は flex を使ってみます。 flex は info がなくて man しかないというやるせない状況ですが、タダなので文句は言いません。 (註:相変わらず用語には無頓着なので不正確なことがあります) flex とは? 正規表現とトークン解析 正規表現とは 正規表現の文法 正規表現の例 flex インプットの概略 C の宣言文 flex の宣言文 トークン規則 C の追加コード 具体例 単純なトークン解析 ちょっと複雑なトークン解析 bison とあわせて使ってみる 中置記法計算機 変数が使える計算機 追記:tab2sp, cpp2html 1.flex とは? flex はスキャナ(scanner)生成プログラムです。スキャナというのは、トークン解析を行うもののことです。flex はそのスキャナを C のコードとして出力します。 スキャナ生成プログラム
C言語では関数内関数は定義できません。関数はファイルスコープでしか定義できない。それがC言語の文法です。Pascal では作れ、FORTRAN でも文関数くらいなら作れるというのに、何でかC言語では作れません。何で作れないようにしたのかは分かりませんが、そうなっているので仕方がありません。 このことはC++でも同じ事のはずなのですが、何とC++では工夫すれば関数内関数が作れてしまいます。C++講座の構造体の章を書いていたら、ふと思いついてしまいました。でやってみたら、何とできるじゃありませんか。びっくりしましたが、聞いてみると結構気づいている人もいるみたいです。 方法は以下の通りです。 関数内で構造体を宣言する。 静的メンバ関数を、構造体宣言内で実装する。 以上です。「ローカル関数は作れません」というエラーが出るものと思っていましたが、コンパイル通りました。動作も問題ありませんでした。 で
主レジスタは、特別な意味を持つこともありますが、普通はどんな利用をしてもいい32ビットレジスタです。16ビット、8ビットのレジスタとしても使え、その際は AX, AH, AL のようになります。AX は EAX の下位16ビット、AH は AX の上位8ビット、AL は AX の下位8ビットになります。H は High の H で、L は Low の L です。 ポインタレジスタは、主としてアドレスを指し示すための32ビットレジスタです。EIP 以外は16ビットレジスタとしても利用でき、その際は先頭の E を除けます。ESP レジスタはスタックの位置を指し示すためのレジスタです。なので、通常直接操作することはありませんが、スタックの位置を直接移動させたいときに操作することがあります。EIP レジスタはプログラムの実行位置を指し示すためのレジスタです。直接操作は許されていません。EBP は関
ここでは、プログラムに関する色々なことを書いていこうと思います。更新は少ないですが、できるだけ役に立つ情報を載せられたらいいと思っています。でも、性根がひねくれているので、変なことばっかり書くかも知れません。(^ ^; なにぶんロベールもまだ未熟者なので、内容に誤りがある可能性があります。もし誤りを見つけたら「あー、こいつバカなこと言ってるぜ」と傍観してないで、メールで知らせて下さい。
Dumping objects -> {16} normal block at 0x00780EC0, 4 bytes long. Data: < > CD CD CD CD Object dump complete. このように、メモリリークがあるとその旨を表示し、アドレスとバイト数、そしてそのデータの内容を表示してくれます。 しかし、これだけでは一体どのコードでメモリリークしたのかがさっぱりわかりません(new int; のところじゃないか、なんて無粋な突っ込みはなしね)。 そのためには operator new(size_t, const char*, int) を作って new する際にファイル名 __FILE__ と行番号 __LINE__ を記録するようにさせればいいわけですが、VC++ではデバッグビルド時に _CRTDBG_MAP_ALLOC というマクロを定義してやれば自動
ポインタ天国最終章、メンバ関数ポインタ天国の始まり始まり〜。 では、今回の要点です。 静的メンバ関数は普通の関数ポインタに代入できる。 メンバ関数ポインタの型名にはクラス名が必要になる。 メンバ関数ポインタを使うときは .* や ->* 演算子が必要。 this->* は省略できない。 では、いってみましょう。 さて。第9章で関数ポインタについて話しました。その冒頭でこういう風に話しました。 関数もアドレスが取れると言いました。アドレスはただの数値です。となると関数のアドレスを入れることのできる変数があってもいいじゃないですか。今回はそういう変数についてのお話です。 これはもちろんメンバ関数にも言えることで、メンバ関数ポインタというのも作ることができます。 では、どんな文法なのかちょっと考えてみましょう。恒例ですね。 先ず、普通の関数ポインタは次のようになるのでしたね。 void Func
メンバ関数ポインタの使い方については前回ので問題ありません。今回は、メンバ関数ポインタについての細かい話をしようと思います。 では、今回の要点です。 メンバ関数ポインタは仮想関数の呼び出しも適切に処理してくれる。 メンバ関数ポインタのサイズは int のサイズと同じとは限らない。 では、いってみましょう。 前回はメンバ関数ポインタの文法と使い方について話しただけだったので、先ずは1つ例でも挙げておきましょう。 // Lane.h // 実行レーンクラス template <typename t_Lane> class CLane { private: // enum はクラスの中でも定義できます // int 型の定数を使いたい場合によくやります enum Const{ LaneSize = 16, }; // レーンのサイズ typedef void (t_Lane::*FPLANE)(
ここは私ロベールの運営するロベールの部屋です。 プログラミング情報サイトとして絶賛更新停滞中です。 ネタがあれば更新するかもしれません。 では、ごゆっくりどうぞ。 C++講座が本になりました なんか凄い紹介されていますが、講座が本になりました。 書かれている通り、かなり内容を変更しています。講座にはいくつかの間違いが含まれていますが、本では可能な限り直してあります。説明の足りない部分、分かりづらい部分、日本語のおかしい部分なども加筆修正してあります。根本的に内容を変更している部分も多いですし(特にクラス関連)、新規に追加した内容もあります。図も大幅に増強して、かなり内容が変わっていると感じるかと思います。 ページ数は 946 ページとかなりの分量(そして分厚さ)になりましたが、途中まで読んだだけでも(エレガントではないまでも)プログラムを組む事ができるように作ってあるので、途中で挫折しても
次のページ
このページを最初にブックマークしてみませんか?
『ロベールの部屋』の新着エントリーを見る
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く