ゲームが作れるようになるまでがんばる日記

ゲーム制作のことを中心にゲームに関することを書いています

C++

lhsとrhs

C++

C++のプログラムを見ていると引数名にlhsやrhsというものを見かける。これはleft-hand sideとright-hand sideの略で、左辺と右辺のこと。2項演算子を実装する関数の仮引数名に使われる。 const Test operator*(const Test& lhs, const Test& rhs);もちろん、…

コピーコンストラクタとコピー代入演算子

C++

コピーコンストラクタとコピー代入演算子の部分の知識が怪しいので復習。 class Test { public: Test(); // デフォルトコンストラクタ Test(const Test& a); // コピーコンストラクタ Test& operator=(const Test& a); // コピー代入演算子 }; Test a; // デ…

__DATE__, __TIME__

C++

定義済みのマクロ名として__DATE__,__TIME__がある。 __DATE__はコンパイルしたときの日付、__TIME__はコンパイルしたときの時刻。 これを使ってプログラムを作成したときの時間を記録しておけば、いくつもバージョンを作ったときにいつのものか判定できて便…

プリプロセッサ演算子#,##

C++

#defineとともに使用する演算子#と##。#はそれに続く引数を引用文字列に変換し、##は2つの文字列を連結する。 #include <iostream> using namespace std; #define MAKESTRING(s) # s #define CONCATENATE(a, b) a ## b int main() { cout << MAKESTRING(This is Test.)</iostream>…

__FILE__,__LINE__,#line

C++

__FILE__はコンパイルされるファイル名を表し、__LINE__はその行数を表す。 #line 行数 "ファイル名"#lineは__FILE__と__LINE__の値を指定することができる。 #include <iostream> using namespace std; int main() { cout << __FILE__<< " " << __LINE__ << endl; #li</iostream>…

#if defined

C++

昨日の日記(id:toburau:20090512)で書いた#if definedの使い方についてコメントをいただいた。ありがとうございます。 次のように複数の条件を組み合わせて使う。 #if defined(マクロ名1) && !defined(マクロ名2) // マクロ名1が定義されていて、かつマクロ…

条件付きコンパイルディレクティブ

C++

いろんな条件付きコンパイルディレクティブをメモ。 #if 式1 // 式1がtrueのとき #elif 式2 // 式2がtrueのとき #else // それ以外 #endif マクロ名が#defineで定義されているかで判定される方法。ちなみに#defineで定義されているのを取り除くのは#undef。 …

#errorディレクティブ

C++

ディレクティブってのはプリプロセッサのコマンドのこと。コードをコンパイルする前にテキストを操作できる。#defineや#includeなど。 で、今回初めて知ったのが#errorディレクティブ。これはコンパイラにコンパイルの中止をさせることができるもの。使い方…

stringからヌル終端文字列の取得

C++

stringからヌル終端文字列、つまりCでよく扱う文字列の形式を得るにはc_str()関数を使う。 #include <iostream> #include <string> using namespace std; int main() { string str1("This is a Test."); const char* p = str1.c_str(); printf("%s\n", p); }</string></iostream>

stringのcompare

C++

stringで文字列の比較を行う場合には==や演算子を使うことができる。しかし文字列の一部分だけを比較したい場合にはcompare()関数を使う。戻り値はCのstrcmpと同じようなもの。 int string.compare( start, num, string2, start2, num2 ); この場合、string…

stringのfind,rfind

C++

stringのメンバ関数find(),rfind()は文字列を検索するもの。 find()は指定した文字列が最初にあらわれたインデックス位置を返し、rfind()は逆に最後にあらわれた位置を返す。 そして、指定した文字列が見つからない時には npos を返す。 #include <iostream> #include <string></string></iostream>…

stringのinsert,replace,erase

C++

文字列を扱うstringのメンバ関数。 insert(start, str); insert(start, str, start2, num); insert()は文字列を挿入する関数。上の形式はstartの位置にstrを挿入し、下の形式はstartの位置にstrのstart2の位置からnum文字を挿入する。 replace(start, num, s…

transform

C++

STLのtransform()アルゴリズムは範囲内の各要素に指定した関数を適用することができるもの。 transform(start, end, result, func); transform(start1, end1, start2, result, func); 上の形式では、startからendの範囲の要素にfuncを適用しresultに格納する…

remove_copy, replace_copy

C++

remove_copy()は指定した値を取り除きながらコピーするアルゴリズムで、replace_copy()は置換しながらコピーするアルゴリズム。 _ifが付いたアルゴリズムはcount_if()と同様に条件を判定する関数を指定して処理を行うもの。 コピー先にはあらかじめコピーで…

カウントアルゴリズム

C++

STLのアルゴリズムの中からカウントアルゴリズムを試してみた。 size_t count(start, end, val); size_t count_if(start, end, func); count()はstartからendの中に指定した値のものの個数を返す。count_if()はfuncで指定した関数がtrueを返すものの個数を返…

STL map

C++

マップは一意のキーと値が対応付けられた結合コンテナのこと。キーとその値のペア。キーからその値を得ることができる。 ゲームっぽくプログラムを書いてみた。ゲーム内のアイテムの名前をキーとして、値はそのアイテムの効果というもの。 #include <iostream> #includ</iostream>…

STL list

C++

リストはsort()関数でソートすることができる。そしてソートされたリスト同士をmerge()関数でマージすることもできる。 #include <iostream> #include <list> using namespace std; int main() { list<int> l1,l2; // ランダムな値でリストを作成 for(int i=0; i<5; i++) { l1.pus</int></list></iostream>…

STL list

C++

listは双方向のリスト。使い方はvectorとあまり変わらない。しかしvectorと違ってランダムアクセスはできず、シーケンシャルアクセスのみ。 push_back() 末尾に要素を追加 push_front() 先頭に要素を追加 pop_back() 最後の要素を削除 pop_front() 先頭の要…

STL vector その3

C++

vectorには自分で作成したクラスのオブジェクトも要素として格納できる。使い方はint型といった組み込み型と変わらない。 #include <iostream> #include <vector> using namespace std; class Test { int num; public: Test(int i) { num = i; } int get() { return num; } }; </vector></iostream>…

STL vector その2

C++

vectorは要素を追加するときにメモリ領域が足りなかったら自動的に拡張してくれる。 メモリ拡張せずにあと、どのくらい要素を追加できるのかを得る関数がcapacity()。この値よりも要素を追加しようとするとメモリ領域の拡張が行われる。 実際に要素を20個追…

STL vector

C++

vectorは動的な配列。配列の要素を増やしていったとき、自動的に配列のメモリを増加してくれる。 メンバ関数で自分がとくに使うであろうものは次のとおり。 push_back() 末尾に要素を追加 pop_back() 最後の要素を削除 size() 要素数を返す begin() 最初の要…

リンケージ指定

C++

C++で作ったオブジェクトファイルはそのままではCのプログラムでリンクできない。これは関数のシンボル名がC++ではオーバーロードなどの情報が含まれるためCとは異なるから。 Cのプログラムでリンクできるようにするためにはリンケージ指定を行う。 リンケー…

黙示的なコンストラクタ変換とexplicit

C++

1つの仮引数をとるコンストラクタを持つクラス。 class Test { int num; public: Test(int x) { num = x; } } オブジェクトの初期化を私は次のように書いている。 Test obj(10); これを次のように書くこともできる。 Test obj = 10; これは自動的に上の書き…

constメンバ関数とmutable

C++

クラスのメンバ関数名の後ろにconstを付けるとオブジェクトの内容を変更できなくなる。 class Test { int num; public: int func(int n) const { num = n; // コンパイルエラー } }; mutableキーワードを付けたメンバ変数はconstメンバ関数でも値を変更でき…

無名ネームスペース

C++

名前を付けないでネームスペースを指定するとそれは無名ネームスペースとなり、そのファイルの中でのみ有効となる。 次のように二つのファイルをコンパイルしてリンクする場合。list1.cppで宣言された無名ネームスペースのiはlist2.cppでexternで参照しよう…

using

C++

毎回、ネームスペース名を付けるのが面倒。そんなときはusing。usingで指定したネームスペースはその後付けなくても良くなる。 namespace MyNameSpace { int i = 123; class Test { ... }; } void func() { using MyNameSpace::i; cout << i << endl; using …

namespace

C++

C++ではネームスペースという名前空間を定義して、外からは見えないようにすることができる。別の名前空間で定義することによって同じ名前のものでも衝突が起きない。 たとえば次のプログラムではMyNameSpaceというネームスペースを定義しており、その中の変…

reinterpret_cast演算子

C++

reinterpret_cast演算子は単なる型変更のキャスト。static_castでは型変換の処理が行われるが、こちらはただ指すものが変わるだけ。無理矢理、その解釈の仕方を変えるという感じかな。 void func() { char c = 'a'; int address = reinterpret_cast<int>(&c); } </int>…

static_cast演算子

C++

static_cast演算子は今まで普通に使ってきたキャストと同じと考えてよいだろう。 int main() { float f = 123.0f; int i; i = static_cast<int>(f); } static_cast演算子を使うと検索で見つけやすくなる利点があるけど、ただ括弧を付けるだけでよかった今までのキ</int>…

const_cast演算子

C++

const_cast演算子はconst属性を取り除くのに使える。 #include <iostream> using namespace std; void func(const int* p) { int* a; a = const_cast<int*>(p); *a = 123; } int main() { int a = 100; func(&a); cout << a << endl; } constをわざわざ付けているのは意味が</int*></iostream>…