ア | イ | ウ | エ | オ |
カ | キ | ク | ケ | コ |
サ | シ | ス | セ | ソ |
タ | チ | ツ | テ | ト |
ナ | ニ | ヌ | ネ | ノ |
ハ | ヒ | フ | ヘ | ホ |
マ | ミ | ム | メ | モ |
ヤ | ユ | ヨ | ||
ラ | リ | ル | レ | ロ |
ワ | ヰ | ヴ | ヱ | ヲ |
ン |
A | B | C | D | E |
F | G | H | I | J |
K | L | M | N | O |
P | Q | R | S | T |
U | V | W | X | Y |
Z | 数字 | 記号 |
標準C++ライブラリのうちSTLに含まれる、ベクター要素を扱うためのクラス。配列と同様の機能を提供する。
#include <vector>
mallocやnewと違い自動的に開放されるため、メモリーリークが起こらない。
C++ Standard Library Defect Report Listの第69項として、std::vectorのメモリー連続性について触れられている。
69. Must elements of a vector be contiguous?
Discussion:
The issue is this: Must the elements of a vector be in contiguous memory?
Proposed resolution:
Add the following text to the end of 23.3.6 [vector], paragraph 1.
The elements of a vector are stored contiguously, meaning that if v is a vector<T, Allocator> where T is some type other than bool, then it obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size().
簡単に訳すと、次のようになる。
69. ベクター要素は連続している必要があるか?
議論:
問題はこれです: ベクター要素は、連続したメモリー内に存在する必要があるか?
決議案:
23.3.6 [ベクター] 第1項の末尾に、次の文を追加する。
ベクター要素は、vがvector<T, Allocator>で、何らかの型Tがbool以外の場合、0 <= n < v.size()の全てにおいて等式&v[n] == &v[0] + nに従うことを意味し、連続的に格納される。
これによれば、「現在の」std::vectorにはメモリーの連続性はあると解釈できる。古い実装では連続していないかもしれないが、そのような古すぎる実装は無視するならば、連続性を理由にmallocやnewなどを使う理由はもはや無い。
必要なだけstd::vectorでメモリーを確保すれば、それは&v[0]から連続したメモリー領域として扱うことができる。メモリーリークに怯える必要は、もはや無いのである。
ベクター要素へのアクセスと要素の追加は、定数時間(大きさに限らず常に一定時間)で完了する。
特定の値の検出、ベクターへの要素挿入は、線形時間(入力の大きさに比例する時間)を要する。
ビット値であるboolのvector、つまりvector<bool>は、標準C++ライブラリでは特殊化して処理している。
複数のビットがパックして処理されることもあり(処理系依存)、メモリー効率がよいこともある。
vector<bool>は、ビットを反転するメソッドとしてflip();が追加され、また演算子=がbool値を参照するようにオーバーロードされる。
文法は次の通り。
vector();
vector(size_type size);
vector(size_type num, const TYPE &val);
vector(const vector &from);
vector(input_iterator start, input_iterator end);
上から順に、次のようにベクターは作られる。
文法は次の通り。
v1 == v2
v1 != v2
v1 <= v2
v1 >= v2
v1 < v2
v1 > v2
v[]
各ベクターは、比較演算子によって比較できる。
各ベクターの個々の要素は[]演算子によって調べられる。先頭へのポインターが必要なら&v[0]で求められるが、C++11では、この目的のために新たにdata()というメソッドが追加された。
assign() | ベクターに要素を割り当てる |
at() | 指定した位置の要素を返す |
back() | 最終要素への参照を返す |
begin() | 先頭を指すイテレーターを返す |
capacity() | ベクターが保持できる要素数を返す |
clear() | 全ての要素を削除する |
empty() | ベクターが空ならtrueを返す |
end() | 末尾の次を指すイテレーターを返す |
erase() | 要素を削除する |
flip() | ビットを反転する (vector<bool>のみ) |
front() | 先頭要素への参照を返す |
get_allocator() | ベクターのアロケーターを返す |
insert() | 要素をベクターに挿入する |
max_size() | ベクターが保持できる最大要素数を返す |
pop_back() | 最終要素を削除する |
push_back() | ベクターの末尾に要素を追加する |
rbegin() | ベクター末尾を指すリバースイテレーターを返す |
rend() | ベクター先頭を指すリバースイテレーターを返す |
reserve() | ベクターが保持できる要素数を設定する |
resize() | ベクターのサイズを変更する |
size() | ベクター中の要素数を返す |
swap() | 二つのベクターを入れ替える |
C++で、オプション文字列をUTF-8のstring型として扱う方法。
♥や♨といった、シフトJISで表わせないものをファイル名としてオプションに渡す場合はUnicodeとしてオプションを受け取る必要があるが、Windows標準のUTF-16、つまりwchar_tでは処理が面倒なだけで何の利点もない。
そこで、普段はUTF-8にして内部で持ち回し、必要な時には再びUTF-16にしてAPIを呼べばよいのである。
CHogeAppクラスのアプリケーションと想定して説明する。
#include <vector> #include <string>
上の他に、必要なヘッダーファイルは逐一includeする(<windows.h>など)。
#ifdef _MSC_VER int wmain(int argc, wchar_t *argv[]) { std::vector<std::string> args(argc); for (int idx = 0; idx < argc; ++idx) { int nLen = WideCharToMultiByte(CP_UTF8, 0, argv[idx], wcslen(argv[idx]), NULL, 0, NULL, NULL); std::vector<char> buf(nLen + 1); nLen = WideCharToMultiByte(CP_UTF8, 0, argv[idx], wcslen(argv[idx]), &buf[0], nLen, NULL, NULL); args[idx] = &buf[0]; } CHogeApp theApp(argc, args); return (int)0; } #else int main(const int argc, const char *argv[]) { std::vector<std::string> args(argc); for (int idx = 0; idx < argc; ++idx) { args[idx] = argv[idx]; } CHogeApp theApp(argc, args); return EXIT_SUCCESS; } #endif
まず必要なmain関数は上記の通りである。Windowsではwmain関数でUTF-16形式のオプション文字列が得られる。UNIX(BSDやLinux等)はいい加減なので、UTF-8環境であればそのままUTF-8の文字列がchar *で得られるため、それをそのままstd::stringに代入する。
CHogeApp::CHogeApp(const int argc, const std::vector<std::string> &args) { Main(argc, args); } CHogeApp::~CHogeApp() { }
コンストラクターとデストラクターは必要に応じて内容を書き換える。主処理はCHogeApp::Mainとする。
void CHogeApp::Main(const int argc, const std::vector<std::string> &args) { ... }
Main関数以降に必要な処理を書けばよい。この時点で、argcの他に、std::string型の引数が得られている。
std::vectorなので、手動でのメモリー解放は不要。また、参照はargs[0]のように、char *型の時と変わらない。先頭アドレスが欲しいときは&args[idx][0]のようにする。
コメントなどを投稿するフォームは、日本語対応時のみ表示されます