【C++】クラスの使い方について詳しく解説

C++において、classはオブジェクト指向プログラミングの重要な概念です。

本記事では、C++のclassの基礎から応用までをわかりやすく解説していきます。

目次

C++のclassとは

C++のclassは、オブジェクト指向プログラミングにおいて重要な役割を担っています。

classは、データとそれに関連する操作をまとめたものであり、プログラム内で複数のインスタンスを生成することができます。

例えば、人間を表すデータを含んだclassを作成する場合、名前や年齢などのデータメンバーと、歩く・走る・話すなどの操作メンバーを定義することができます。

class Person {
    string name;
    int age;
    int job;
    void Walk(int distance);
    void Run(int distance);
    void Talk(string message);
};

そして、このclassから複数の人間インスタンスを生成することができます。

int main() {

    Person p1;
    Person p2;
    Person p3;

    return 0;
}

classの使い方

C++において、classはオブジェクト指向プログラミングの基本的な概念です。classを使用することで、複数の変数や関数をまとめて扱うことができます。

メンバ変数の定義と呼び出し方

class内で宣言された変数はメンバ変数と呼ばれます。メンバ変数は、通常の変数と同じように宣言することができます。以下は、SampleClassという名前のclass内にint型のメンバ変数を宣言する例です。

class SampleClass {
public:
    int sampleVariable;
};

このように宣言されたメンバ変数は、以下のようにして呼び出すことができます。

SampleClass sampleObject;
sampleObject.sampleVariable = 10;

メンバ関数の定義と呼び出し方

class内で宣言された関数はメンバ関数と呼ばれます。

メンバ関数も通常の関数と同じように宣言することができます。以下は、SampleClass内にprintSample()という名前のメンバ関数を宣言・実装する例です。

class SampleClass {
public:
    void printSample() {
        std::cout << "This is a sample function." << std::endl;
    }
};

このように宣言されたメンバ関数は、以下のようにして呼び出すことができます。

SampleClass sampleObject;
sampleObject.printSample();

また、通常の関数と同じようにプロトタイプ宣言を行い、別の場所(class内に限る)に実装部分を記述することも可能です。

class SampleClass {
public:
    void void printSample();

    //...ほかの宣言・定義など

    void printSample() {
        std::cout << "This is a sample function." << std::endl;
    }
};

コンストラクタとデストラクタの定義

コンストラクタは、オブジェクトが生成される際に自動的に呼び出される特殊なメソッドです。デストラクタは、オブジェクトが破棄される際に自動的に呼び出される特殊なメソッドです。

以下は、SampleClass内にコンストラクタ・デストラクタを定義する例です。

#include <iostream>

class SampleClass {
public:
    // コンストラクタ
    SampleClass() {
        std::cout << "コンストラクタが呼ばれました。" << std::endl;
    }

    // デストラクタ
    ~SampleClass() {
        std::cout << "デストラクタが呼ばれました。" << std::endl;
    }
};

int main() {
    SampleClass sam;
    std::cout << "Hello, World!" << std::endl;

    return 0;
}
コンストラクタが呼ばれました。
Hello, World!
デストラクタが呼ばれました。

上記コードは、SampleClassのsam変数を宣言したタイミングでオブジェクトが生成、コンストラクタが呼ばれてコンストラクタが呼ばれました。と表示されます。

その後Hello, World!が出力され、main関数が終了してsamがメモリから破棄される直前でデストラクタが呼ばれてデストラクタが呼ばれました。が表示されます。

コンストラクタ・デストラクタも通常のメソッド同様、publicprivateprotectedキーワードを用いてアクセス制御を行うことができます。また、引数を取ることも可能です。

以上がC++でclassを定義する方法やその使い方について説明した内容です。

classのアクセス指定子

C++のclassには、メンバ変数やメンバ関数に対してアクセス制限を設けることができます。

これを実現するために、アクセス指定子というものが用意されています。

public

publicは、class外部からでもアクセス可能なメンバ変数やメンバ関数を定義するための指定子です。

つまり、publicで宣言されたメンバ変数やメンバ関数は、class外部からでも自由に呼び出すことができます。

以下は、publicで宣言されたメンバ変数とメンバ関数の例です。

class SampleClass {
public:
    int publicVar; // publicなメンバ変数
    void publicFunc() { // publicなメンバ関数
        std::cout << "Hello World!" << std::endl;
    }
};

publicVarとpublicFunc()はどちらもpublic指定子の下に定義されているため、自由にどこでも呼び出すことが可能です。

int main() {
    SampleClass sam;
    sam.publicVar = 100;
    sam.publicFunc();
    std::cout << sam.publicVar << std::endl;

    return 0;
}
Hello World!
100

private

privateは、class内部からしかアクセスできないようにするための指定子です。つまり、privateで宣言されたメンバ変数やメンバ関数は、class外部から直接呼び出すことができません。

以下は、privateで宣言されたメンバ変数とメンバ関数の例です。

class SampleClass {
private:
    int publicVar; // privateなメンバ変数
    void publicFunc() { // privateなメンバ関数
        std::cout << "Hello World!" << std::endl;
    }
};

以下のコードでは、SampleClassの変数と関数を呼び出そうとしていますが、どちらもprivate指定子の下で宣言・定義されているため、外部からアクセスすることができずコンパイルエラーになります。

int main() {
    SampleClass sam;
    sam.publicVar = 100; //エラー
    sam.publicFunc(); //エラー
    std::cout << sam.publicVar << std::endl;

    return 0;
}

主にクラス内でのみ使用するものをprivateにして、アクセス制限を行うことが一般的です。

protected

protectedは、継承した派生クラスからもアクセス可能なようにするための指定子です。

つまり、protectedで宣言されたメンバ変数やメンバ関数は、その派生クラス内部からでも自由に呼び出すことができます。ただし、元のクラス・派生クラス以外からは直接呼び出すことができません。

以下は、protectedで宣言されたメンバ変数とメンバ関数の例です。

#include <iostream>

class BaseClass {
protected:
    int protectedVar; // protectedなメンバ変数
    void protectedFunc() { // protectedなメンバ関数
        std::cout << "Hello World!" << std::endl;
    }
};

// BaseClassを継承したDerivedClassを作成する。
class DerivedClass : public BaseClass {
public:
    void callProtectedFunc() {
        protectedFunc(); // BaseClass内部では呼び出せる。
    }
};

int main() {
    DerivedClass deri;
    deri.callProtectedFunc(); //publicなので呼び出せる
    deri.protectedFunc(); //protectedなので呼び出せずエラーになる

    return 0;
}

public protected privateを上手く活用して変数や関数へのアクセスを制限・管理することで、意図しない変数の代入が発生したり、可読性が下がってしまうのを防ぐことができます。

classのオブジェクトの生成と利用

オブジェクトの生成

classを定義したら、そのclassからオブジェクトを生成することができます。オブジェクトは、classのインスタンスです。

// MyClassという名前のclassを定義する
class MyClass {
public:
    int myInt;
};

int main() {
    // MyClassからmyObjという名前のオブジェクトを生成する
    MyClass myObj;

    return 0;
}

上記の例では、MyClassからmyObjという名前のオブジェクトを生成しています。このように、MyClass myObj; のように書くことで、MyClass型の変数であるmyObjが作成されます。

オブジェクトの利用

オブジェクトを使用するには、ドット演算子(.)を使用してメンバ変数やメンバ関数にアクセスします。

// MyClassという名前のclassを定義する
class MyClass {
public:
    int myInt;
    void printMyInt() {
        cout << "myInt = " << myInt << endl;
    }
};

int main() {
    // MyClassからmyObjという名前のオブジェクトを生成する
    MyClass myObj;

    // メンバ変数に値を代入する
    myObj.myInt = 42;

    // メンバ関数を呼び出す
    myObj.printMyInt();

    return 0;
}

上記の例では、myObj.myInt = 42; を使用してメンバ変数に値を代入し、myObj.printMyInt(); を使用してメンバ関数printMyInt() を呼び出しています。

終わりに

classはオブジェクト指向プログラミングにおいて非常に重要な概念であり、しっかりと理解しておくことが必要です。

また、実際に手を動かして簡単なクラスを作成したり、継承や仮想関数を利用したクラスを作成することで、より深く理解することができるので、たくさんのエラーを起こしながら正しくclassを扱う方法を身に着けていくといいでしょう。

目次