読者です 読者をやめる 読者になる 読者になる

【初心者 C++er Advent Calendar 2015 11日目】C++ における class と struct の違い

C++

この記事は初心者 C++er Advent Calendar 2015の11日目の記事になります。
今日はクリスマス・イブ!!ってことで、せっかくなので穴が空いていた11日目の記事を書きました。
クリスマスとか早く爆発してほしい


さて、C言語にデータ構造を定義するための struct という機能がありました。
C++ では更にクラスを定義するための class という機能が新たに加わりました。

struct とは

C 言語ではデータ構造を定義するための機能です。
例えば、次のように独自データを定義することができます。

struct person{
    int id;
    int age;
    char name[20];
};

person homu = { 0, 14, "homu" };

C言語の場合は typedef する必要があるが、今回は C++ の例題なので省略。

class とは

class とは簡単に言うと『structに関数が定義できるようになった』ようなものです。

class person{
    // アクセシビリティ
    // public 以下は全部公開される
public:
    int id;
    int age;
    std::string name;

    // 情報を出力する関数
    void
    print(){
        std::cout << "id:"   << id << std::endl;
        std::cout << "age:"  << age << std::endl;
        std::cout << "name:" << name << std::endl;
    }
};

person homu = { 0, 14, "homu" };
homu.print();
//  * [output]
//
// id:0
// age:14
// name:homu

このように class は自身に対して関数を定義して、自身の変数を参照したりできます。
また、他にもオブジェクト指向でいう継承や多態性などと言った機能もあります。

C++ における struct

ここまでの説明で、
「ほーなるほどねー class って変数だけじゃなくて関数を定義できるのが struct と違うんだー」
と、思ったかも知れませんが、実は C++ では class だけではなくて struct でも関数を定義することができます。

// class ではなくて struct
struct person{
    int id;
    int age;
    std::string name;

    // 情報を出力する関数
    void
    print(){
        std::cout << "id:"   << id << std::endl;
        std::cout << "age:"  << age << std::endl;
        std::cout << "name:" << name << std::endl;
    }
};

person homu = { 0, 14, "homu" };
homu.print();
//  * [output]
//
// id:0
// age:14
// name:homu

ほぼ一緒ですね。

C++ における class と struct の違い

「じゃあ結局 classstruct って何が違うの?」
というのですが、これは

という違いになります。
例えば以下の2つの定義は同等になります。

struct X{
    // デフォルトのアクセシビリティは public
    int get_value();
private:
    int value;
};

class X{
    // デフォルトのアクセシビリティは private
    int value;
public:
    int get_value();
};

このように struct では public がデフォルト、class では private デフォルト、という形になります。
また、スコープ内での定義以外でも継承するクラスのアクセシビリティも同じです。

struct X : /* デフォルトでは public 継承 */ Base{
    
};

class X : /* デフォルトでは private 継承 */ Base{
    
};

逆に言えってしまえば、C++classstruct はデフォルトのアクセシビリティ以外の違いはありません。
以上が『C++ における class と struct の違い』になります。

おまけ

classstruct が機能的にはほぼ一緒と言うことはわかったと思いますが、どう使い分ければいいのかはいまいちよくわからないと思います。
これに関しては人それぞれ(クラスっぽいものは class にしたり、データ構造は struct にしたりect...)だと思いますが、わたしは、

  • 上部に public を定義
  • 下部に private を定義

するという理由から class ではなくて struct のみを使用しています。
具体的には以下のような感じです。

struct X{
    // 公開するメンバ関数
    int get_value();
private:
    // 非公開なメンバ変数
    int value;
};

// class を使う場合は、以下のように無駄に public をつける必要がある
// class X{
// public:             // class の場合は上部に public をつける必要がある
//     int get_value();
// private:
//     int value;
// };

こんな感じです。
まぁあとはメタプログラミングをやっているとどうしても継承する機会が多くなって、継承するたびにいちいち public をつけるのがめんどくさいので struct を使ってるというのもありますが。
このあたりは自分のスタイルに合わせて決めているとよいと思います。