| (同じ利用者による、間の2版が非表示) | |||
| 60行目: | 60行目: | ||
== ビットフィールド == | == ビットフィールド == | ||
メモリの使用を最適化するために、構造体内でビットフィールドが使用できる。<br> | メモリの使用を最適化するために、構造体内でビットフィールドが使用できる。<br> | ||
これは、個々のビットレベルでデータを管理することができる。<br> | |||
<br> | |||
このようなビットフィールドの使用は、メモリが制限されている環境やハードウェアレジスタと直接やり取りする必要がある場合等、<br> | |||
効率的なメモリ使用が重要な場面で特に有用である。<br> | |||
<syntaxhighlight lang="c++"> | <syntaxhighlight lang="c++"> | ||
struct Flags { | struct Flags { | ||
unsigned int flag1 : 1; | unsigned int flag1 : 1; // 1[bit]のフィールドとして定義されており、本質的にブール値 (0 または 1) が格納できる | ||
unsigned int flag2 : 1; | unsigned int flag2 : 1; // 1[bit]のフィールドとして定義されており、本質的にブール値 (0 または 1) が格納できる | ||
unsigned int data : 6; | unsigned int data : 6; // 6[bit]のフィールドとして定義されており、0 から 63 (2^6 - 1) の範囲の値が格納できる | ||
}; | }; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | |||
<syntaxhighlight lang="c++"> | |||
Flags f; | |||
f.flag1 = 1; // フラグをオンに設定 | |||
f.flag2 = 0; // フラグをオフに設定 | |||
f.data = 42; // 6ビットの範囲内の値を設定 | |||
if (f.flag1) { | |||
// flag1 がオンの場合の処理 | |||
} | |||
// data の値を出力 (0 - 63の範囲) | |||
std::cout << "Data value: " << f.data << std::endl; | |||
</syntaxhighlight> | |||
<br> | |||
この構造体の特徴とメリットを以下に示す。<br> | |||
* メモリ効率 | |||
*: 一般的に、unsigned int型は32[bit] (4[byte]) を使用する。 | |||
*: この構造体は合計で8[ビット] (1[byte]) しか使用しない。 | |||
*: 結果として、メモリ使用量が75[%]削減される。 | |||
*: <br> | |||
* パッキング | |||
*: コンパイラは、これらのビットフィールドを1つのunsigned int型にパックする。 | |||
*: <br> | |||
* アクセス | |||
*: これらのフィールドは、通常の構造体のメンバのようにアクセスできるが、値は自動的に適切なビット数に制限される。 | |||
<br><br> | <br><br> | ||
| 223行目: | 253行目: | ||
if (stat("example.txt", &file_info) == 0) { | if (stat("example.txt", &file_info) == 0) { | ||
// file_infoを使ってファイル情報にアクセス | // file_infoを使ってファイル情報にアクセス | ||
} | |||
</syntaxhighlight> | |||
<br><br> | |||
== nullptrの代替 == | |||
<code>std::optional</code>を使用することにより、<code>nullptr</code>のような振る舞いを実現することができる。<br> | |||
<u>ただし、C++17以降で利用可能である。</u><br> | |||
<br> | |||
この記述は、以下に示すようなメリットがある。<br> | |||
* 関数が値を持っているかどうかを明示的に示すことができる。 | |||
* 呼び出し側において、値の存在を確認した後に使用することを強制することができる。 | |||
<br> | |||
<syntaxhighlight lang="c++"> | |||
#include <string> | |||
#include <vector> | |||
#include <optional> | |||
struct HOGE { | |||
int i; | |||
double f; | |||
bool b; | |||
std::string str; | |||
}; | |||
class SomeClass | |||
{ | |||
private: | |||
std::vector<HOGE> m_hoges; | |||
public: | |||
std::optional<HOGE> getHoge() const | |||
{ | |||
if (m_hoges.empty()) { | |||
return std::nullopt; | |||
} | |||
return m_hoges[0]; | |||
} | |||
}; | |||
// 使用例 | |||
void someFunction() | |||
{ | |||
SomeClass obj; | |||
auto result = obj.getHoge(); | |||
if (result.has_value()) { | |||
HOGE hoge = result.value(); | |||
// ...略 | |||
} | |||
else { | |||
// データが存在しない場合の処理 | |||
// ...略 | |||
} | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
また、C++17のif文と構造化束縛を使用して、より簡潔に記述することもできる。<br> | |||
<syntaxhighlight lang="c++"> | |||
if (auto hoge = obj.getHoge(); hoge) { | |||
// *hogeを使用する処理 | |||
} | |||
else { | |||
// データが存在しない場合の処理 | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||