CとC++の構造体の違い

  • 0
    いいね
  • 1
    コメント

    これは 初心者C++ Advent Calendar 2016 12日目の記事です。
    大遅刻してごめんなさい :bow:

    Cの構造体

    Cの構造体は、いくつかの変数をまとめて扱えるようにしたものです。
    若干タプルに近いような気がする。

    struct Point
    {
        double x;
        double y;
    };
    

    struct まで含めて1つの型として扱われるので、型名は struct Point と書かないとコンパイルエラーになります。ただ Point と書きたかったら、適当に typedef するのがいいんじゃないでしょうか。

    使用する際は変数宣言の後に各メンバに代入するか、宣言時に {} でくくって初期化するのが一般的だと思います。
    下記の2つのコードはどちらも同様の処理をしますが、前者は宣言時のメンバが不定値なので気をつけてください。

    struct Point p;
    p.x = 1.5;
    p.y = 2.4;
    
    struct Point p = {1.5, 2.4};
    

    C++の構造体

    C++の構造体は、メンバがデフォルトでpublicなクラスです。メンバ関数が使え、アクセス指定もできます。

    struct Point
    {
        double x;
        double y;
    
        Point(double x, double y) : x(x), y(y){}
        double r(){ return sqrt(x * x + y * y); }
        double theta(){ return atan2(y, x); }
    };
    

    コンストラクタだけだとちょっと寂しい気がしたので、極座標に変換できるようにしてみました。
    Cと違って struct をつけなくても変数宣言ができ、コンストラクタで初期化ができます。

    {}での初期化も健在です。

    Point p(1.5, 2.4);
    
    Point p = {1.5, 2.4};
    

    試してみたところ、{}での初期化はコンストラクタをそのまま呼び出しているように見えます。
    実際にどうなっているか調べたらまた追記します。

    struct hoge
    {
        int x;
    
        hgoe(int x) : x(x){ cout << "hoge constructor" << endl; }
    };
    
    hoge h1(10); // "hoge constructor"
    hoge h2 = {20}; // "hoge constructor"
    

    ちなみに、クラスはデフォルトが private です。

    class Point
    {
        double x;
        double y;
    
        Point(double x, double y) : x(x), y(y){}
        double r(){ return sqrt(x * x + y * y); }
        double theta(){ return atan2(y, x); }
    };
    
    point p(1.5, 2.4); // コンパイルエラー
    

    構造体も、明示宣言することでメンバをprivateにできます。

    struct point
    {
        hgoe(double x, double y) : x(x), y(y){}
    
    private:
        double x;
        double y;
    };
    
    point p(1.5, 2.4);
    cout << p.x << endl; // コンパイルエラー
    

    まとめ

    • C++の構造体はデフォルトが public なクラス
    • 型名に struct を入れずに宣言できる
    • アクセス指定ができる