C++プログラミングにおいて、クラスは非常に重要な概念です。クラスを使うことで、データと関数をひとまとめにし、より構造化されたコードを書くことができます。本記事では、C++でクラスを作成する方法を、初心者の方にも分かりやすく解説していきます。実際のコード例を交えながら、クラスの基本から応用までを段階的に学んでいきましょう。
クラスとは?
クラスは、オブジェクト指向プログラミングの中心的な概念です。簡単に言えば、クラスは「データ」と「そのデータを操作する関数」をまとめたものです。クラスを使うことで、現実世界のものや概念をプログラム内で表現しやすくなります。
例えば、「車」というクラスを作る場合、車の特徴(ブランド、モデル、年式など)をデータとして持ち、車に関する操作(走る、止まる、情報を表示するなど)を関数として定義します。
基本的なクラスの作り方
では、実際にC++でクラスを作ってみましょう。まずは、簡単な「車」クラスを作成します。
#include <iostream>
#include <string>
class Car {
private:
std::string brand;
std::string model;
int year;
public:
// コンストラクタ
Car(std::string b, std::string m, int y) {
brand = b;
model = m;
year = y;
}
// メンバー関数
void display() {
std::cout << year << " " << brand << " " << model << std::endl;
}
};
int main() {
Car myCar("Toyota", "Corolla", 2022);
myCar.display();
return 0;
}
このコードを詳しく見ていきましょう。
class Car
で、Car
という名前のクラスを定義しています。private:
の下にある変数(brand
,model
,year
)は、クラスの外部からアクセスできないプライベートメンバーです。public:
の下にある関数は、クラスの外部からアクセスできるパブリックメンバーです。Car(std::string b, std::string m, int y)
は「コンストラクタ」と呼ばれる特別な関数で、オブジェクトが作成されるときに自動的に呼び出されます。void display()
は、車の情報を表示するメンバー関数です。main()
関数で、Car
クラスのオブジェクトを作成し、display()
関数を呼び出しています。
このプログラムを実行すると、「2022 Toyota Corolla」と表示されます。
クラスの改良:ゲッターとセッター
上記のクラスでは、プライベートメンバーに直接アクセスすることができません。これは良いカプセル化の例ですが、時にはこれらの値を取得したり設定したりする必要があります。そのために、「ゲッター」と「セッター」と呼ばれる関数を追加します。
class Car {
private:
std::string brand;
std::string model;
int year;
public:
Car(std::string b, std::string m, int y) : brand(b), model(m), year(y) {}
// ゲッター
std::string getBrand() const { return brand; }
std::string getModel() const { return model; }
int getYear() const { return year; }
// セッター
void setBrand(const std::string& b) { brand = b; }
void setModel(const std::string& m) { model = m; }
void setYear(int y) { year = y; }
void display() {
std::cout << year << " " << brand << " " << model << std::endl;
}
};
この改良版では以下の点が変更されています:
- コンストラクタでメンバー初期化リストを使用しています。これは効率的な初期化方法です。
- 各プライベートメンバーに対してゲッター関数を追加しました。これらの関数は
const
キーワードを使用して、オブジェクトの状態を変更しないことを保証しています。 - セッター関数を追加し、プライベートメンバーの値を外部から変更できるようにしました。
これらの変更により、クラスの使用者は以下のようにオブジェクトの属性にアクセスできます:
int main() {
Car myCar("Toyota", "Corolla", 2022);
std::cout << "Brand: " << myCar.getBrand() << std::endl;
myCar.setYear(2023);
myCar.display(); // 2023 Toyota Corolla と表示されます
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;
public:
Car(std::string b, std::string m, int y);
std::string getBrand() const;
std::string getModel() const;
int getYear() const;
void setBrand(const std::string& b);
void setModel(const std::string& m);
void setYear(int y);
void display() const;
};
#endif // CAR_H
次に、メンバー関数の実装(通常は .cpp
ファイルに記述):
// Car.cpp
#include "Car.h"
#include <iostream>
Car::Car(std::string b, std::string m, int y) : brand(b), model(m), year(y) {}
std::string Car::getBrand() const { return brand; }
std::string Car::getModel() const { return model; }
int Car::getYear() const { return year; }
void Car::setBrand(const std::string& b) { brand = b; }
void Car::setModel(const std::string& m) { model = m; }
void Car::setYear(int y) { year = y; }
void Car::display() const {
std::cout << year << " " << brand << " " << model << std::endl;
}
この方法を使うと、クラスの定義(インターフェース)と実装を明確に分離でき、大規模なプロジェクトでの管理が容易になります。
C++でクラスを作成することは、オブジェクト指向プログラミングの基本であり、大規模なプログラムを効率的に設計・実装する上で非常に重要です。この記事で紹介した基本的な概念を理解し、実際にコードを書いて練習することで、クラスの使い方に慣れていくことができます。さらに学習を進めると、継承やポリモーフィズムといったより高度な概念も扱えるようになり、より柔軟で強力なプログラムを作成できるようになります。
コメント