その9 メモリブロッククラス(v1.01)
色々な型のデータをシーケンシャルにメモリに格納していくクラスです。
名前 | バージョン | 公開日 | |
メモリブロック | 1.01 | 2010. 1.9 |
モデルデータやビットマップの絵の情報など、沢山の値が連続で並ぶ情報は一塊で扱えると便利です。メモリブロッククラスはそういう様々なデータを連続的に(シーケンシャル)にメモリに格納していきます。扱い方は非常にシンプルです。データを格納するには左シフト(<<)演算子を用います。データにアクセスするには配列([ ])演算子を用います。詳しい使い方は後述のコードをご覧下さい。
このクラスは内部でスマートポインタ(dixsmartptr.h)を使用しています。dixsmartptr.hが同じフォルダ内に無いとコンパイルエラーになりますのでご注意ください。
○ 定義
名前空間 | ヘッダー |
Dix | MemBlock.h |
○ メモリブロッククラスメンバメソッド
公開メンバメソッド | 説明 | 使い方 | 備考 |
MemBlock() |
コンストラクタ | MemBlock mb; | コンストラクタではmallocによる空メモリの確保が行われます。 |
~MemBlock( void ) | デストラクタ | - | - |
unsigned size() | 格納サイズを取得 | MemBlock mb; mb << 100; unsigned sz = mb.size() |
格納されたメモリブロックのサイズを取得します。 |
MemBlock& push( const void *src, unsigned data ) | データを追加 | MemBlock mb; mb.push( "Test", 5 ); |
メモリブロックの最後尾に指定サイズだけデータを追加します。 |
演算子 | 説明 | 使い方 | 備考 |
const char &operator []( int e ) const | データにアクセス | MemBlock mb; mb << "ABCDE"; const char str = mb[3]; // C |
格納されているデータにアクセスします。データの先頭ポインタを得るにはこの演算子を通し、 const char *ptr = &mb[0]; として下さい。 |
MemBlock &operator <<( const char* str ); MemBlock &operator <<( const MemBlock &src ); template< class T> MemBlock &operator <<( const T &src ); |
データを追加 | MemBlock mb; mb << 100 << "Test" << 12.345f; MemBlock mb2; mb2 << mb1 << "End"; |
メモリブロックの最後尾にデータを追加します。戻り値はMemBlockなので使い方にあるように<<演算子を連続して適用できます。 文字列は終端文字が含まれます。 テンプレート定義がされているので型固定(サイズ固定)のデータであれば構造体でも何でも格納できます。 |
○ バージョンレポート
v1.00 -> 1.01(2010. 1. 9)
・ pushメソッド追加
v1.00 (2010. 1. 8)
・ 初出実装
○ 使い方
#include "stdafx.h"
#include "memblock.h"
struct MYDATA {
int a;
float b;
double c;
char str[7];
MYDATA() : a(100), b(200.0f), c(300.456) {
memcpy( str, "MyData", 7 );
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Dix::MemBlock mb;
mb << "This is a Test !\n";
printf( &mb[0] );
// 保存テスト
Dix::MemBlock mb3;
MYDATA myData;
myData.a = 9999;
myData.b = 8888.8f;
myData.c = 777.777;
memcpy( &myData.str, "<Text>", 7 );
mb3 << myData; // 保存
// 読み込みテスト
MYDATA loadData;
memcpy( &loadData, &mb3[0], sizeof(MYDATA) ); // 読み込み
printf("%d, %f, %f, %s", loadData.a, loadData.b, loadData.c, loadData.str );
printf("\n");
return 0;
}
コードにあるように左シフト演算子でメモリブロックに格納します。
コピーについて、このクラスはメモリブロックへのポインタをスマートポインタで包んでいます。よって代入演算子や関数に渡す場合にはポインタの共有が行われ、メモリのハードコピーは行われません。関数の引数にする場合は実体渡しでも特に問題ありませんが、可能であればアドレス渡しをした方が効率的です:
// 実体渡し
void func( MemBlock block ) {
block << "Data" << 12345;
}
// アドレス渡し
// こちらの方が内部でスマートポインタの参照カウンタに使うnewが発生しない分効率的です
void func2( MemBlock &block ) {
block << "Data" << 12345;
}