定数の記述場所
外部に公開する必要があるものはヘッダーに
公開する必要がないものは、cppファイルに書きましょう。
アロケータの使い方
作成したアロケータの使い方
#include <vector> // 64バイトアラインメントでメモリ確保を行うvector std::vector<char, CAllocator<char, 64> > buffer;
アロケータの作り方
STL標準のstd::allocatorには、アラインメントを操作する機能がないので
確保したいメモリのアイランメントを設定したい場合、自前でアロケータを作る必要がある
#include <malloc.h> typedef unsigned long uint32; // デフォで4バイトアラインメント template <class T, uint32 N = 4> class CAllocator : public std::allocator<T> { public: typedef uint32 size_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef T value_type; // メモリを割り当てる pointer allocate(size_type num, const void* hint = 0) { return (pointer)memalign(N, num * sizeof(T)); } // メモリを解放する void deallocate(pointer p, size_type num) { free(p); } // 割当てることができる最大の要素数を返す size_type max_size() const { struct mallinfo memInfo = mallinfo(); return memInfo.fordblks; } };
max_sizeの処理が正しくないけど、スルーでお願いします^^
mallinfoは、構造体と関数の両方があるので、構造体として使用する場合、C++でもstructを付ける必要があります。
セーブとロードでの型違いは×
固定長のものはセーブとロードが同一環境であるならば、構造体にして
その構造体をそのままセーブ、ロードすることで問題ない。
しかし、可変長のものはそうはいかないので、可変した際の数やらなんやらを保存しなくてはいけない。
今回、std::mapを使っていたのもを保存したわけだが、前に容量が大きくなりすぎたので
型をunsigned intからunsigned shortに変更したことがある。
それで、セーブのときは、std::map::iterator::firstとstd::map::iterator::secondを
使えばよいので問題ないが、ロードの際は一度この値を読み込んだ後に
設定しなければいけない。
その読み込む際に、読み込む変数がunsigned int型で読み込んでいたため
読み込みにずれが生じてしまった。
可変長のデータを扱うときは注意しましょう。
ひどいプログラムを見た
こんなのがあった。一瞬何をやっているかわからなかった。
if (IsHoge()) { // いろいろ } else if (IsHogeHoge()); else { // いろいろ }
普通こうだろ
if (IsHoge()) { // いろいろ } else if (!IsHogeHoge()) { // いろいろ }