Menu
Coddy logo textTech

Struct と Class

CoddyのC++ジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 37/104。

C++において、structclassはほぼ同一です。どちらもメンバ変数、メンバ関数、コンストラクタを持つことができ、継承をサポートしています。唯一の違いは、それらのデフォルトのアクセスレベルです。

class内では、メンバーはデフォルトで非公開(private)です。struct内では、メンバーはデフォルトで公開(public)です:

struct Point {
    int x;    // デフォルトでpublic
    int y;    // デフォルトでpublic
};

class Circle {
    double radius;    // デフォルトでprivate
    
public:
    double getRadius() { return radius; }
};

これは継承にも当てはまります。structはデフォルトでパブリックに継承しますが、classはプライベートに継承します:

struct DerivedStruct : Base {};    // パブリック継承
class DerivedClass : Base {};      // プライベート継承

これらのデフォルト設定を除けば、技術的な違いはありません。しかし、慣習は重要です。

ほとんどのC++プログラマーは、公開メンバを持つ単純なデータコンテナ(座標や設定など)には struct を使用し、カプセル化や振る舞いが重要な場合には class を使用します。この慣習に従うことで、他の開発者に対してコードの意図がより明確になります。

challenge icon

チャレンジ

簡単

C++の慣習に基づき、structclassをいつ使い分けるかを示すシンプルな設定システムを構築しましょう。オープンにアクセスすることを目的としたシンプルなデータにはstructを、カプセル化と制御されたアクセスが必要なデータにはclassを作成します。

コードを整理するために2つのファイルを作成します:

  • Config.h: 異なる種類の設定データを表す構造体とクラスの両方を定義します。

    まず、幅と高さ(両方とも int)を保持するシンプルなデータコンテナである Dimensions という struct を作成します。構造体はデフォルトでメンバが公開(public)されているため、これらはゲッターなしで直接アクセスできる必要があります。幅と高さの積を返す area() メソッドを含めてください。

    次に、適切なカプセル化を行ってアプリケーション設定を管理する AppConfig という class を作成します。これには、アプリ名(string)とウィンドウサイズ用の Dimensions オブジェクトを格納する必要があります。クラスのメンバはデフォルトで非公開(private)であるため、公開インターフェースを明示的にアクセス可能にする必要があります。以下を提供してください:

    • アプリ名、幅、高さを引数に取るコンストラクタ
    • 名前を返すゲッター getAppName()
    • Dimensions を返すゲッター getWindowSize()
    • "App: <name>, Window: <width>x<height>, Area: <area>" と出力する displayConfig() メソッド
  • main.cpp: 構造体とクラスの使用法の違いを実演します。入力からアプリ名、幅、高さ(3つの別々の行)を読み取り、以下の処理を行います:
    • 幅と高さの値を使用して Dimensions 構造体を直接作成し、そのメンバに直接アクセスして "Direct struct access: <width> x <height>" と出力します。
    • 3つの値すべてを使用して AppConfig オブジェクトを作成します。
    • displayConfig() を呼び出して、完全な設定を表示します。
    • ゲッターを使用してウィンドウの寸法を取得し、"Via getter - Area: <area>" と出力します。

このチャレンジは、「座標や寸法のようなシンプルで透過的なデータには struct を使い、アクセスを制御しデータに関連する振る舞いを追加したい場合には class を使う」という慣習を強調しています。

std::stoi() を使用して、入力された幅と高さの文字列を整数に変換してください。ヘッダーファイルにはヘッダーガードを忘れずに追加してください。

チートシート

C++において、structclassはほぼ同一ですが、1つの重要な違いがあります。それは、デフォルトのアクセスレベルです。

structでは、メンバはデフォルトでpublicです:

struct Point {
    int x;    // デフォルトでpublic
    int y;    // デフォルトでpublic
};

classでは、メンバはデフォルトでprivateです:

class Circle {
    double radius;    // デフォルトでprivate
    
public:
    double getRadius() { return radius; }
};

これは継承にも適用されます:

struct DerivedStruct : Base {};    // デフォルトでpublic継承
class DerivedClass : Base {};      // デフォルトでprivate継承

慣習: 公開メンバを持つ単純なデータコンテナにはstructを使用し、カプセル化や振る舞いが重要な場合にはclassを使用します。

自分で試してみよう

#include <iostream>
#include <string>
#include "Config.h"

using namespace std;

int main() {
    // 入力を読み込む
    string appName;
    string widthStr;
    string heightStr;
    
    getline(cin, appName);
    getline(cin, widthStr);
    getline(cin, heightStr);
    
    int width = stoi(widthStr);
    int height = stoi(heightStr);
    
    // TODO: width と height を持つ Dimensions 構造体を作成する
    // そのメンバに直接アクセスして "Direct struct access: <width> x <height>" と出力する
    
    // TODO: appName、width、height を使用して AppConfig オブジェクトを作成する
    
    // TODO: AppConfig オブジェクトで displayConfig() を呼び出す
    
    // TODO: getWindowSize() ゲッターを使用してディメンションを取得し、"Via getter - Area: <area>" と出力する
    
    return 0;
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン