ロベール本

ロベール完読

長かった。でもとても面白かった。

可変長配列メンバ

ロベールのC++入門講座 16-14クラスのメンバ変数の配列の要素数を可変長にするテクニックの話です。まず配列の要素を一つだけで宣言しておきます。 class CSample { public: int m_int; char m_char[1]; }; そしてこのクラスを定義する際に、クラスのサイズ…

匿名共用体

ロベールのC++入門講座 16-02メンバ変数に匿名共用体を用いれば、メモリを共有するメンバ変数を定義できます。 #include <iostream> using std::cout; using std::endl; class CSample { public: union { int m_int; char m_char[4]; }; }; int main () { CSample obj;</iostream>…

メンバ変数ポインタ

ロベールのC++入門講座 13-17メンバ関数のポインタは以前勉強しました。実はメンバ変数もポインタを取ることができます。 #include <iostream> using std::cout; using std::endl; class CSample { public: int m_x; int m_y; CSample(int x,int y) { m_x = x; m_y = y</iostream>…

テンプレートの部分特殊化 応用編

ロベールのC++入門講座 13-13テンプレートの部分特殊化については以前テンプレートの部分特殊化 - (void*)Pないとにて勉強しました。このときやった実装例は、ある型とその型のポインタで部分特殊化するというものでしたが、それ以外にも複雑な部分特殊化も…

実体定義でテンプレートの特殊化

ロベールのC++入門講座 13-13テンプレートの特殊化にはクラス宣言で特殊化する方法と、実体定義で特殊化する方法があります。前者は以前テンプレートの部分特殊化 - (void*)Pないとにて勉強しました。後者は今回勉強する内容になります。実体定義でテンプレ…

基底クラスの関数を派生クラスでprivateに変更する

ロベールのC++入門講座 13-11前回のusingの応用です。 #include <iostream> class CBase { public: void func(char*); void func(int); }; class CSub : public CBase { private: // 基底クラスのfunc関数をprivateにする using CBase::func; }; void CBase::func (cha</iostream>…

usingを利用した継承関係でのオーバーロードのような処理

ロベールのC++入門講座 13-11 #include <iostream> class CBase { public: void func(int); }; class CSub : public CBase { public: void func(char*); }; void CBase::func (int num) { std::cout << num << std::endl; } void CSub::func (char *str) { std::cout <</iostream>…

引数有りコンストラクタを持つクラスを仮想継承する際の注意

ロベールのC++入門講座 13-04引数有りのコンストラクタを持つクラスを仮想継承し、それを多重継承した場合のお話です。以下の例を見てみましょう。 #include <iostream> using std::cout; using std::endl; class CBase { public: CBase (int num) { m_num = num; } in</iostream>…

クロスキャスト

ロベールのC++入門講座 13-08例えば以下のような多重継承の関係のクラスがあるとします。 class CBaseA { public: virtual ~CBaseA() {} }; class CBaseB { public: virtual ~CBaseB() {} }; class CSample : public CBaseA, public CBaseB {}; この状態でCB…

暗黙のキャスト

ロベールのC++入門講座 11-12 暗黙のキャストは思わぬバグを引き起こしてしまう可能性もあります。そのため、引数が一つになる可能性のあるコンストラクタがあれば、コピーコンストラクタを除いて、とりあえずはexplicitをつけておいたほうが無難です。 なる…

演算子のオーバーロードをフレンド関数に登録する

ロベールのC++入門講座 11-11グローバルな演算子のオーバーロードをするときに、その対象のクラスのプライベートな変数や関数が見えたほうが良いケースがあります。そういう場合のために予めクラス側で対象となる演算子のオーバーロードをフレンド関数に登録…

シングルトンクラス

ロベールのC++入門講座 11-03シングルトンクラスというものに関して言及がありました。コンストラクタをprivateにすることで外部でインスタンス化を不可能にし、そのクラスのオブジェクトが必ず一つしか存在しないことを保証するクラスのことをシングルトン…

例外の再送出

ロベールのC++入門講座 10-05例外が発生して関数を抜ける前に何かしらの後処理がしたい場合、以下のように例外の再送出を使います。 #include <iostream> using std::cout; using std::endl; void func () { int* p = NULL; try { p = new int[10]; throw "エラー発生</iostream>…

関数tryブロック

ロベールのC++入門講座 10-08コンストラクタの初期化子で発生した例外をキャッチする方法として関数tryブロックというものがあります。 #include <iostream> #include <string> using std::cout; using std::endl; class CSample { public: CSample (std::string str) try: m_s</string></iostream>…

テンプレート定義時のtypenameとclassの違い

ロベールのC++入門講座 09-02 template<typename T> ... と template<class T> ... において、動作の違いはまったくないそうです。ただし古いコンパイラではtypenameだと対応していない可能性があるらしいです。とりあえず本ブログではタイプ量の少ないclassを使っていきたいと思</class></typename>…

無名の名前空間

ロベールのC++入門講座 08-13namespaceを名前無しで定義すると無名の名前空間になります。 namespace { int i = 100; } こうして定義されたi変数はスコープがファイル内(ブロック内ではないことに注意)に限られます。 // -- main.cpp -- #include <iostream> namespa</iostream>…

別名の名前空間を定義する

ロベールのC++入門講座 08-13namespaceによる名前空間の別名を定義することができます。 #include <iostream> namespace FooBarBaz { int i = 10; } // 別名の定義 namespace FBB = FooBarBaz; int main () { // アクセスできる std::cout << FBB::i << std::endl; ret</iostream>…

テンプレートの実装のエクスポート

ロベールのC++入門講座 09-08テンプレートの実装をヘッダに書かなければならない理由 - (void*)Pないとの続きです。前回の記事でテンプレートの実装はヘッダで書かなければならないと言っていましたが、実はexportという指定子(?)を使えばヘッダに宣言だけを…

関数テンプレートにテンプレート引数のデフォルト値が渡せない理由

ロベールのC++入門講座 09-08前にテンプレートの勉強をした時に疑問に思ってた部分ですが、ロベール本で少し言及がありました。 実は関数テンプレートのテンプレート引数の場合はデフォルト引数をとることができません。これはおそらく、関数テンプレートの…

テンプレート引数の記述を省略する

ロベールのC++入門講座 09-07タイトルがちょっとわかり辛いですが、例を見ればすぐわかると思います。まず以下の処理を見てください。 template<class T> class CSample { public: CSample<T>& operator=(const CSample<T>& obj) { // 中身は適当。とりあえず自分自身を返し</t></t></class>…

テンプレートの実装をヘッダに書かなければならない理由

ロベールのC++入門講座 09-03ロベール本ではテンプレートの実装はヘッダに書かなければならないとさらりと書かれていましたが、何故そうしないといけないのかが本を読むだけでは今一良くわからなかったので色々調べてみたところ、理由がわかりました。まず宣…

バイナリモードでファイルの読み込み

ロベールのC++入門講座 08-09fstreamクラスを使ってのバイナリモードでファイルの読み込みをやってみます。 #include <iostream> #include <fstream> using std::cout; using std::endl; int main () { std::fstream file; char buf[16]; file.open("main.cpp",std::ios::in|std</fstream></iostream>…

バイトオーダー

ロベールのC++入門講座 08-08生データをバイナリモードで出力する場合、環境によってデータのバイトの並びが昇順になったり降順になったりするそうです。このバイトの並びのことをバイトオーダーと呼びます。そして昇順(左から右へ)の並びをビッグエンディア…

生データのファイル入出力

ロベールのC++入門講座 08-08C言語のときにもやりましたね。C++ではfstreamで同様のことが可能です。 #include <iostream> #include <fstream> #include <string> using std::cout; using std::endl; int main (int argc,const char* argv[]) { std::string type("w"); if ( argc >= 2 )</string></fstream></iostream>…

fstreamクラスでファイルのコピー処理

ロベールのC++入門講座 08-09ファイルのコピーを実装します。 #include <iostream> #include <fstream> using std::cout; using std::endl; int main () { std::fstream file1; std::fstream file2; char buf[16]; file1.open("main.cpp",std::ios::in|std::ios::binary); if ( </fstream></iostream>…

stringstreamクラス

ロベールのC++入門講座 08-03文字列をcoutやcinのような扱い方と同じように扱えるようにしたのがstringstreamクラスです。使用例を見てみましょう。 #include <iostream> #include <sstream> using namespace std; int main () { stringstream sstr; sstr.str(""); sstr << "abc</sstream></iostream>…

stringクラスはヌルターミネーターを必要としない

ロベールのC++入門講座 08-01stringクラスはその文字列の長さを自前で管理しているため、ヌルターミネーターを使わなくても問題ない。それどころからヌルターミネーターを一つの文字列として認識することさえ可能である。 #include <iostream> #include <string> using namespa</string></iostream>…

仮想関数テーブル

ロベールのC++入門講座 07-09仮想関数テーブルという内部実装の話。ある仮想関数を呼ぼうとしたときに、実際にどの関数が呼ばれるのかという情報が書き込まれた表のこと。クラスの隠しメンバ変数にその情報を持っているのでクラスのサイズが増える。また仮想…

ファイルの読み書きfstreamクラス

ロベールのC++入門講座 08-04ファイルの読み書きはC言語のときに色々やりましたが、C++ではまだ殆どやってませんでした。当然Cのようにfopen等で同じような実装もできるのですが、折角なのでC++特有のファイルの読み書きの方法を勉強したいと思います。fstre…