MENU

C++ クラスを作ろうPart2

C++プログラミングを学ぶ上で、クラスの概念を理解することは非常に重要です。クラスは、オブジェクト指向プログラミングの中核をなす要素であり、データと機能をまとめて管理する強力なツールです。本記事では、C++でクラスを作成する方法を、初心者の方にも分かりやすく、そして詳細に解説していきます。

目次

クラスとは何か?

クラスは、データ(メンバ変数)と、そのデータを操作する関数(メンバ関数)をひとまとめにした「設計図」のようなものです。実世界の物事をプログラムで表現する際に非常に便利な概念です。

例えば、「車」というクラスを考えてみましょう。車には以下のような特徴があります:

  • データ(属性):
    • ブランド
    • モデル
    • 製造年
  • 機能(操作):
    • 走る
    • 止まる
    • 情報を表示する

これらの要素を、C++のクラスとして表現することができます。

基本的なクラスの作成

それでは、実際にC++でクラスを作成してみましょう。まずは、基本的な「車」クラスを定義します。

#include <iostream>
#include <string>

class Car {
private:
    std::string brand;
    std::string model;
    int year;
    std::string color;

public:
    // コンストラクタ
    Car(std::string b, std::string m, int y, std::string c) 
        : brand(b), model(m), year(y), color(c) {}

    // メンバ関数
    void displayInfo() {
        std::cout << year << " " << brand << " " << model << " (" << color << ")" << std::endl;
    }

    void drive() {
        std::cout << brand << " " << model << " is driving." << std::endl;
    }

    void stop() {
        std::cout << brand << " " << model << " has stopped." << std::endl;
    }
};

int main() {
    Car myCar("Toyota", "Corolla", 2022, "Blue");
    myCar.displayInfo();
    myCar.drive();
    myCar.stop();

    return 0;
}

このコードを詳しく見ていきましょう:

  1. class Car で、Carという名前のクラスを定義しています。
  2. private: キーワードの後に、クラスの外部からアクセスできないメンバ変数(brand, model, year, color)を定義しています。これらは車の属性を表します。
  3. public: キーワードの後に、クラスの外部からアクセス可能なメンバ関数を定義しています。
  4. Car(std::string b, std::string m, int y, std::string c) はコンストラクタです。新しい Car オブジェクトを作成するときに呼び出され、初期値を設定します。: brand(b), model(m), year(y), color(c) はメンバ初期化リストで、効率的にメンバ変数を初期化します。
  5. displayInfo(), drive(), stop() はメンバ関数で、それぞれ車の情報表示、運転、停止の動作を表現しています。
  6. main() 関数では、Car クラスのオブジェクト myCar を作成し、そのメンバ関数を呼び出しています。

このプログラムを実行すると、以下のような出力が得られます:

2022 Toyota Corolla (Blue)
Toyota Corolla is driving.
Toyota Corolla has stopped.

カプセル化とアクセス制御

上記の例では、privatepublic キーワードを使用しています。これは「カプセル化」という重要な概念の一部です。

  • private メンバは、クラスの外部から直接アクセスできません。これにより、データの不適切な変更を防ぎ、整合性を保つことができます。
  • public メンバは、クラスの外部からアクセス可能です。通常、クラスの機能を提供するインターフェースとして使用されます。

しかし、時には private メンバの値を取得したり設定したりする必要があります。そのために、「ゲッター」と「セッター」と呼ばれる関数を追加します:

class Car {
private:
    std::string brand;
    std::string model;
    int year;
    std::string color;

public:
    Car(std::string b, std::string m, int y, std::string c) 
        : brand(b), model(m), year(y), color(c) {}

    // ゲッター
    std::string getBrand() const { return brand; }
    std::string getModel() const { return model; }
    int getYear() const { return year; }
    std::string getColor() const { return color; }

    // セッター
    void setColor(const std::string& c) { color = c; }

    // その他のメンバ関数は省略...
};

このように改良すると、以下のようにオブジェクトの属性にアクセスできます:

int main() {
    Car myCar("Toyota", "Corolla", 2022, "Blue");
    std::cout << "Brand: " << myCar.getBrand() << std::endl;
    
    myCar.setColor("Red");
    std::cout << "New color: " << myCar.getColor() << std::endl;
    
    return 0;
}

ゲッターとセッターを使用することで、データへのアクセスを制御しつつ、必要に応じて値の取得や変更が可能になります。

クラスの定義と実装の分離

プロジェクトが大きくなるにつれて、クラスの定義(宣言)と実装を別々のファイルに分けることが一般的になります。これにより、コードの管理が容易になり、再利用性も向上します。

まず、ヘッダーファイル(通常は .h または .hpp 拡張子を使用)にクラスの定義を記述します:

// Car.h
#ifndef CAR_H
#define CAR_H

#include <string>

class Car {
private:
    std::string brand;
    std::string model;
    int year;
    std::string color;

public:
    Car(std::string b, std::string m, int y, std::string c);

    std::string getBrand() const;
    std::string getModel() const;
    int getYear() const;
    std::string getColor() const;

    void setColor(const std::string& c);

    void displayInfo() const;
    void drive() const;
    void stop() const;
};

#endif // CAR_H

次に、実装ファイル(.cpp 拡張子を使用)にメンバ関数の定義を記述します:

// Car.cpp
#include "Car.h"
#include <iostream>

Car::Car(std::string b, std::string m, int y, std::string c)
    : brand(b), model(m), year(y), color(c) {}

std::string Car::getBrand() const { return brand; }
std::string Car::getModel() const { return model; }
int Car::getYear() const { return year; }
std::string Car::getColor() const { return color; }

void Car::setColor(const std::string& c) { color = c; }

void Car::displayInfo() const {
    std::cout << year << " " << brand << " " << model << " (" << color << ")" << std::endl;
}

void Car::drive() const {
    std::cout << brand << " " << model << " is driving." << std::endl;
}

void Car::stop() const {
    std::cout << brand << " " << model << " has stopped." << std::endl;
}

この方法を使うことで、クラスのインターフェース(ヘッダーファイル)と実装(ソースファイル)を明確に分離できます。これは大規模なプロジェクトでのコード管理を容易にし、コンパイル時間の短縮にも寄与します。

C++でクラスを作成することは、オブジェクト指向プログラミングの基礎となる重要なスキルです。この記事で紹介した基本的な概念を理解し、実際にコードを書いて練習することで、クラスの使い方に慣れていくことができます。クラスを適切に設計し利用することで、より構造化され、保守性の高いプログラムを作成することができます。

さらに学習を進めると、継承やポリモーフィズム、テンプレートクラスなど、より高度なC++の機能を使いこなせるようになり、より柔軟で強力なプログラムを作成できるようになります。C++プログラミングの世界は奥深く、常に新しいことを学ぶ機会があります。基礎をしっかり固めた上で、少しずつ高度な概念に挑戦していくことをお勧めします。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次