C++の基礎 - 構造体

提供:MochiuWiki - SUSE, Electronic Circuit, PCB
2024年8月19日 (月) 16:24時点におけるWiki (トーク | 投稿記録)による版 (ページの作成:「== 概要 == 構造体は、異なるデータ型の要素をグループ化するためのユーザ定義データ型である。<br> これにより、関連するデータを1つの単位として扱うことができる。<br> <br> C++における構造体の特徴として、以下に示すものが挙げられる。<br> C言語とは異なることに注意する。<br> * メンバアクセス *: メンバには、<code>.</code>演算子でアクセスする…」)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
ナビゲーションに移動 検索に移動

概要

構造体は、異なるデータ型の要素をグループ化するためのユーザ定義データ型である。
これにより、関連するデータを1つの単位として扱うことができる。

C++における構造体の特徴として、以下に示すものが挙げられる。
C言語とは異なることに注意する。

  • メンバアクセス
    メンバには、.演算子でアクセスする。
    構造体へのポインタを使用する場合、->演算子でメンバにアクセスする。
  • デフォルトはpublic
    クラスと異なり、構造体のメンバはデフォルトでpublicである。
  • 継承可能
    構造体は他の構造体やクラスを継承することができる。



構文

 struct <構造体名> {
    データ型1 メンバ1;
    データ型2 メンバ2;
    // ...
 };


 // 例:
 
 struct Person {
    std::string name;
    int age;
    double height;
 };
 
 int main()
 {
    Person p1;
    p1.name = "田中太郎";
    p1.age = 30;
    p1.height = 175.5;
 }



使用例



構造体ポインタ

構造体へのポインタを使用する場合、->演算子でメンバにアクセスする。

 Person* pPtr = &p1;
 pPtr->name = "鈴木花子";



構造体の配列

構造体の配列を作成して、複数のデータセットを管理することができる。

 Person people[3] = {
    {"山田一郎", 25, 170.0},
    {"佐藤二郎", 35, 180.0},
    {"高橋三郎", 45, 165.5}
 };



メソッド

C++では、構造体内にメソッドを定義することもできる。

 struct Rectangle {
    double width;
    double height;
 
    double area() {
       return width * height;
    }
 };



構造体のアライメント

以下に示す方法により、構造体のアライメントを制御することができる。

※注意 1
Clangは、以下に示す全ての方法をサポートしている。
ただし、特定のターゲットプラットフォームやClangのバージョンにより、サポートされる機能や動作が若干異なる可能性があることに注意する。

※注意 2

  • アライメントの変更は、プラットフォーム依存の問題を引き起こす可能性がある。
  • 一部のCPUアーキテクチャでは、アライメントされていないメモリアクセスがパフォーマンスの低下やクラッシュを引き起こす可能性がある。
  • クロスプラットフォーム開発を行う場合は、異なるコンパイラやプラットフォームでの動作を確認する必要がある。


アライメントの変更が必要かどうかを検討して、可能な限り標準的なアライメントを使用することを推奨する。

GNU C/C++の属性を使用する方法

GCC / Clangで動作する。

 struct __attribute__((packed)) MyStruct {
    // 構造体のメンバ
 };


プラグマを使用する方法

GCC / Clangで動作する。

 #pragma pack(push, 1)
 
 struct MyStruct {
    // 構造体のメンバ
 };
 
 #pragma pack(pop)


Clang特有の属性を使用する方法

Clangのみ動作する。

 struct [[gnu::packed]] MyStruct {
    // 構造体のメンバ
 };


C++11以降の標準属性を使用する方法

GCC / Clangで動作する。

 struct alignas(1) MyStruct {
    // 構造体のメンバ
 };


※注意

  • __attribute__((packed))#pragma pack(1) を使用する場合、構造体全体が1バイトアライメントになる。
  • alignas(1) を使用する場合、構造体全体のアライメントは1バイトになるが、個々のメンバは自然なアライメントを保持する。
    完全に詰めたパッキングが必要な場合は、__attribute__((packed))#pragma pack(1) の方が適している。
  • クロスプラットフォーム開発を行う場合は、異なるコンパイラやプラットフォームでの互換性を確認することが重要である。
  • アライメントの変更は、特に必要な場合にのみ行うべきである。
    不適切なアライメントは、パフォーマンスの低下や一部のアーキテクチャでは問題を引き起こす可能性がある。



Linux固有の情報

Linuxシステムにおいて、多くのシステムコールやライブラリ関数は構造体を使用してデータを受け渡しする。
例えば、struct statはファイル情報を格納するために使用される。

 #include <sys/stat.h>
 
 struct stat file_info;
 if (stat("example.txt", &file_info) == 0) {
    // file_infoを使ってファイル情報にアクセス
 }