C++ でクラスとオブジェクトを作成する

C++C++Beginner
今すぐ練習

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

この実験では、C++ プログラミングにおいてクラスとオブジェクトを作成する方法を学びます。プライベートなデータメンバを持つクラスを定義し、パブリックなメンバ関数を実装し、異なるパラメータを持つコンストラクタを作成し、リソースのクリーンアップのためのデストラクタを書き、アクセス指定子を使用し、クラス間の継承を実装し、基底クラスのメソッドをオーバーライドし、アクセス制御のためのフレンド関数を作成し、静的メンバとメソッドを使用します。これらの概念は、C++ におけるオブジェクト指向プログラミングの基礎であり、より複雑なアプリケーションを構築するための堅牢な基礎を提供します。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL cpp(("C++")) -.-> cpp/BasicsGroup(["Basics"]) cpp(("C++")) -.-> cpp/FunctionsGroup(["Functions"]) cpp(("C++")) -.-> cpp/OOPGroup(["OOP"]) cpp/BasicsGroup -.-> cpp/data_types("Data Types") cpp/FunctionsGroup -.-> cpp/function_parameters("Function Parameters") cpp/OOPGroup -.-> cpp/classes_objects("Classes/Objects") cpp/OOPGroup -.-> cpp/class_methods("Class Methods") cpp/OOPGroup -.-> cpp/access_specifiers("Access Specifiers") cpp/OOPGroup -.-> cpp/constructors("Constructors") cpp/OOPGroup -.-> cpp/encapsulation("Encapsulation") cpp/OOPGroup -.-> cpp/inheritance("Inheritance") cpp/OOPGroup -.-> cpp/polymorphism("Polymorphism") subgraph Lab Skills cpp/data_types -.-> lab-446079{{"C++ でクラスとオブジェクトを作成する"}} cpp/function_parameters -.-> lab-446079{{"C++ でクラスとオブジェクトを作成する"}} cpp/classes_objects -.-> lab-446079{{"C++ でクラスとオブジェクトを作成する"}} cpp/class_methods -.-> lab-446079{{"C++ でクラスとオブジェクトを作成する"}} cpp/access_specifiers -.-> lab-446079{{"C++ でクラスとオブジェクトを作成する"}} cpp/constructors -.-> lab-446079{{"C++ でクラスとオブジェクトを作成する"}} cpp/encapsulation -.-> lab-446079{{"C++ でクラスとオブジェクトを作成する"}} cpp/inheritance -.-> lab-446079{{"C++ でクラスとオブジェクトを作成する"}} cpp/polymorphism -.-> lab-446079{{"C++ でクラスとオブジェクトを作成する"}} end

プライベートなデータメンバを持つクラスを定義する

C++ におけるクラスは、オブジェクトを作成するためのブループリントです。それは、クラスから作成されるオブジェクトが持つ一連のプロパティ(データメンバ)とメソッド(メンバ関数)を定義します。クラスは、コードの整理や、カプセル化、継承、ポリモーフィズムなどのオブジェクト指向プログラミングの原則の実装に役立ちます。

C++ でクラスを定義する基本的な構文は以下の通りです。

class ClassName {
private:
    // プライベートなデータメンバ
    int dataMember1;
    std::string dataMember2;

public:
    // パブリックなメンバ関数
    void memberFunction1();
    int memberFunction2();
};

C++ には、クラスメンバの可視性とアクセシビリティを制御する 3 つのアクセス指定子があります。

  • privateprivate として宣言されたメンバは、クラス内のみでアクセス可能です。
  • publicpublic として宣言されたメンバは、クラスの外部からアクセス可能です。
  • protectedprotected として宣言されたメンバは、クラス内および派生クラスのインスタンスからアクセス可能です。

このステップでは、C++ でプライベートなデータメンバを持つクラスを定義する方法を学びます。プライベートなデータメンバは、オブジェクトの内部状態をカプセル化して保護するためのオブジェクト指向プログラミングにおける重要な概念です。

まず、WebIDE を開き、~/project ディレクトリに移動します。student.cpp という新しいファイルを作成します。

touch ~/project/student.cpp

WebIDE で student.cpp ファイルを開き、以下のコードを追加して、プライベートなデータメンバを持つ Student クラスを定義します。

#include <iostream>
#include <string>

class Student {
private:
    // プライベートなデータメンバ
    std::string name;
    int age;
    double gpa;

public:
    // 後のステップでこれらのプライベートメンバとやり取りするメソッドを追加します
    void displayInfo() {
        std::cout << "Name: " << name << std::endl;
        std::cout << "Age: " << age << std::endl;
        std::cout << "GPA: " << gpa << std::endl;
    }
};

int main() {
    Student student;
    // 注:直接プライベートメンバにアクセスすることはできません
    // student.name = "John"; // これはコンパイルエラーを引き起こします

    student.displayInfo();
    return 0;
}

重要な概念を解説しましょう。

  1. プライベートなデータメンバ:

    • private: アクセス指定子を使用して宣言されます
    • クラスの外部から直接アクセスできません
    • データ保護とカプセル化を提供します
  2. データ型:

    • std::string name:学生の名前を格納します
    • int age:学生の年齢を格納します
    • double gpa:学生の平均基点を格納します
  3. カプセル化:

    • プライベートメンバは、パブリックメソッドを通じてのみアクセスできます
    • 内部データの直接の変更を防止します

プログラムをコンパイルします。

g++ student.cpp -o student
./student

プログラムを実行したときの例の出力:

Name:
Age: 0
GPA: 0

要点:

  • プライベートメンバは外部からのアクセスから隠されています
  • クラスメソッドを通じてのみ変更できます
  • これにより、データの整合性と制御が維持されます

パブリックなメンバ関数を実装する

このステップでは、C++ でパブリックなメンバ関数を実装する方法を学びます。パブリックなメンバ関数は、プライベートなデータメンバへの制御されたアクセスを可能にし、クラスオブジェクトとやり取りする方法を提供します。

WebIDE で student.cpp ファイルを開き、Student クラスを変更してパブリックなメンバ関数を含めます。

#include <iostream>
#include <string>

class Student {
private:
    std::string name;
    int age;
    double gpa;

public:
    // プライベートなデータメンバを変更するセッターメソッド
    void setName(std::string studentName) {
        name = studentName;
    }

    void setAge(int studentAge) {
        if (studentAge > 0 && studentAge < 120) {
            age = studentAge;
        } else {
            std::cout << "Invalid age!" << std::endl;
        }
    }

    void setGPA(double studentGPA) {
        if (studentGPA >= 0.0 && studentGPA <= 4.0) {
            gpa = studentGPA;
        } else {
            std::cout << "Invalid GPA!" << std::endl;
        }
    }

    // プライベートなデータメンバにアクセスするゲッターメソッド
    std::string getName() {
        return name;
    }

    int getAge() {
        return age;
    }

    double getGPA() {
        return gpa;
    }

    // 学生情報を表示するディスプレイメソッド
    void displayInfo() {
        std::cout << "Student Information:" << std::endl;
        std::cout << "Name: " << name << std::endl;
        std::cout << "Age: " << age << std::endl;
        std::cout << "GPA: " << gpa << std::endl;
    }
};

int main() {
    Student student;

    // パブリックなメンバ関数を使用してデータを設定および取得する
    student.setName("Alice Johnson");
    student.setAge(20);
    student.setGPA(3.75);

    // 学生情報を表示する
    student.displayInfo();

    // ゲッターメソッドのデモ
    std::cout << "\nStudent Name: " << student.getName() << std::endl;
    std::cout << "Student Age: " << student.getAge() << std::endl;
    std::cout << "Student GPA: " << student.getGPA() << std::endl;

    return 0;
}

プログラムをコンパイルして実行します。

g++ student.cpp -o student
./student

例の出力:

Student Information:
Name: Alice Johnson
Age: 20
GPA: 3.75

Student Name: Alice Johnson
Student Age: 20
Student GPA: 3.75

パブリックなメンバ関数に関する要点:

  • プライベートなデータメンバへの制御されたアクセスを提供する
  • セッターは検証付きで変更を許可する
  • ゲッターはプライベートなデータの読み取りを許可する
  • カプセル化とデータの整合性を維持するのに役立つ

異なるパラメータを持つコンストラクタを作成する

このステップでは、C++ で異なるパラメータを持つコンストラクタを作成する方法を学びます。コンストラクタは、オブジェクトが作成されるときにオブジェクトを初期化する特別なメンバ関数です。

WebIDE で student.cpp ファイルを開き、Student クラスを変更して複数のコンストラクタを含めます。

#include <iostream>
#include <string>

class Student {
private:
    std::string name;
    int age;
    double gpa;

public:
    // デフォルトコンストラクタ
    Student() {
        name = "Unknown";
        age = 0;
        gpa = 0.0;
    }

    // 名前パラメータを持つコンストラクタ
    Student(std::string studentName) {
        name = studentName;
        age = 0;
        gpa = 0.0;
    }

    // 名前と年齢パラメータを持つコンストラクタ
    Student(std::string studentName, int studentAge) {
        name = studentName;
        age = studentAge;
        gpa = 0.0;
    }

    // すべてのパラメータを持つ完全コンストラクタ
    Student(std::string studentName, int studentAge, double studentGPA) {
        name = studentName;
        age = studentAge;
        gpa = studentGPA;
    }

    // 学生情報を表示するディスプレイメソッド
    void displayInfo() {
        std::cout << "Student Information:" << std::endl;
        std::cout << "Name: " << name << std::endl;
        std::cout << "Age: " << age << std::endl;
        std::cout << "GPA: " << gpa << std::endl;
    }
};

int main() {
    // 異なるコンストラクタを使用する
    Student student1;  // デフォルトコンストラクタ
    Student student2("Alice Johnson");  // 名前を持つコンストラクタ
    Student student3("Bob Smith", 22);  // 名前と年齢を持つコンストラクタ
    Student student4("Charlie Brown", 20, 3.75);  // 完全コンストラクタ

    std::cout << "Student 1:" << std::endl;
    student1.displayInfo();

    std::cout << "\nStudent 2:" << std::endl;
    student2.displayInfo();

    std::cout << "\nStudent 3:" << std::endl;
    student3.displayInfo();

    std::cout << "\nStudent 4:" << std::endl;
    student4.displayInfo();

    return 0;
}

プログラムをコンパイルして実行します。

g++ student.cpp -o student
./student

例の出力:

Student 1:
Student Information:
Name: Unknown
Age: 0
GPA: 0

Student 2:
Student Information:
Name: Alice Johnson
Age: 0
GPA: 0

Student 3:
Student Information:
Name: Bob Smith
Age: 22
GPA: 0

Student 4:
Student Information:
Name: Charlie Brown
Age: 20
GPA: 3.75

コンストラクタに関する要点:

  • コンストラクタはクラスと同じ名前を持つ
  • オブジェクトのデータメンバを初期化する
  • 異なるパラメータを持つ複数のコンストラクタを持つことができる
  • オブジェクトが作成されるときに自動的に呼び出される

リソースクリーンアップのためのデストラクタを書く

このステップでは、C++ におけるデストラクタについて学びます。デストラクタは、オブジェクトが破棄されるときにリソースのクリーンアップを担当する特別なメンバ関数です。デストラクタを書く方法と、メモリ管理におけるその重要性を理解しましょう。

WebIDE で student.cpp ファイルを開き、デストラクタと動的メモリ割り当てを含めるようにコードを変更します。

#include <iostream>
#include <string>

class Student {
private:
    std::string name;
    int age;
    double gpa;
    char* dynamicBuffer;  // 動的メモリ割り当てをシミュレート

public:
    // コンストラクタ
    Student() {
        name = "Unknown";
        age = 0;
        gpa = 0.0;
        dynamicBuffer = new char[50];  // 動的メモリを割り当てる
        std::cout << "Default Constructor Called" << std::endl;
    }

    Student(std::string studentName) : name(studentName), age(0), gpa(0.0) {
        dynamicBuffer = new char[50];
        std::cout << "Parameterized Constructor Called" << std::endl;
    }

    // デストラクタ
    ~Student() {
        // 動的に割り当てられたメモリをクリーンアップ
        delete[] dynamicBuffer;
        std::cout << "Destructor Called for " << name << std::endl;
    }

    void displayInfo() {
        std::cout << "Student Information:" << std::endl;
        std::cout << "Name: " << name << std::endl;
        std::cout << "Age: " << age << std::endl;
        std::cout << "GPA: " << gpa << std::endl;
    }
};

int main() {
    // オブジェクトの作成と破棄を示す
    {
        std::cout << "Creating first student:" << std::endl;
        Student student1("Alice Johnson");
        student1.displayInfo();

        std::cout << "\nCreating second student:" << std::endl;
        Student student2("Bob Smith");
        student2.displayInfo();
    }  // ここでオブジェクトはスコープ外になり、デストラクタが呼び出される

    std::cout << "\nExiting main function" << std::endl;
    return 0;
}

プログラムをコンパイルして実行します。

g++ student.cpp -o student
./student

例の出力:

Creating first student:
Parameterized Constructor Called
Student Information:
Name: Alice Johnson
Age: 0
GPA: 0

Creating second student:
Parameterized Constructor Called
Student Information:
Name: Bob Smith
Age: 0
GPA: 0

Destructor Called for Bob Smith
Destructor Called for Alice Johnson

Exiting main function

デストラクタに関する要点:

  • ~ で始まり、クラス名の後に定義される
  • オブジェクトが破棄されるときに自動的に呼び出される
  • 動的に割り当てられたリソースを解放するために使用される
  • メモリリークを防ぐのに役立つ
  • 戻り値の型もパラメータもない

重要なデストラクタの特性:

  • オブジェクトがスコープ外になるときに呼び出される
  • コンパイラによって自動的に呼び出される
  • 動的メモリのクリーンアップに不可欠
  • システムリソースを効率的に管理するのに役立つ

アクセス指定子 (public、private、protected) を使用する

このステップでは、C++ におけるアクセス指定子と、それがクラスメンバの可視性とアクセシビリティをどのように制御するかについて学びます。public、private、protected のアクセスレベルの違いを調べます。

WebIDE で student.cpp ファイルを開き、アクセス指定子を示すようにコードを変更します。

#include <iostream>
#include <string>

class Student {
private:
    // プライベートメンバ:クラス内のみでアクセス可能
    std::string name;
    int age;
    double gpa;

protected:
    // プロテクテッドメンバ:クラス内およびその派生クラス内でアクセス可能
    std::string school;

public:
    // パブリックメンバ:どこからでもアクセス可能
    Student(std::string studentName, int studentAge, double studentGPA) {
        name = studentName;
        age = studentAge;
        gpa = studentGPA;
        school = "Default School";
    }

    // プライベートメンバへのアクセスを示すパブリックメソッド
    void displayInfo() {
        std::cout << "Student Information:" << std::endl;
        std::cout << "Name: " << name << std::endl;  // プライベートメンバへのアクセス
        std::cout << "Age: " << age << std::endl;
        std::cout << "GPA: " << gpa << std::endl;
        std::cout << "School: " << school << std::endl;
    }

    // プライベートメンバを変更するパブリックメソッド
    void updateGPA(double newGPA) {
        if (newGPA >= 0.0 && newGPA <= 4.0) {
            gpa = newGPA;
        }
    }
};

class GraduateStudent : public Student {
public:
    GraduateStudent(std::string name, int age, double gpa)
        : Student(name, age, gpa) {
        // 基底クラスのプロテクテッドな'school' メンバにアクセス可能
        school = "Graduate School";
    }

    void displaySchool() {
        std::cout << "School: " << school << std::endl;
    }
};

int main() {
    Student student("Alice Johnson", 20, 3.75);
    student.displayInfo();  // プライベートメンバにアクセスするパブリックメソッド

    // 以下の行をコメントアウト解除するとコンパイルエラーが発生します
    // student.name = "John";  // エラー:プライベートメンバにアクセスできません
    // student.age = 25;       // エラー:プライベートメンバにアクセスできません

    student.updateGPA(3.90);  // パブリックメソッドを通じてプライベートメンバを変更する
    student.displayInfo();

    GraduateStudent gradStudent("Bob Smith", 25, 3.90);
    gradStudent.displayInfo();
    gradStudent.displaySchool();

    return 0;
}

プログラムをコンパイルして実行します。

g++ student.cpp -o student
./student

例の出力:

Student Information:
Name: Alice Johnson
Age: 20
GPA: 3.75
School: Default School
Student Information:
Name: Alice Johnson
Age: 20
GPA: 3.90
School: Default School
Student Information:
Name: Bob Smith
Age: 25
GPA: 3.90
School: Graduate School
School: Graduate School

アクセス指定子に関する要点:

  • private:メンバは同じクラス内のみでアクセス可能
  • protected:メンバはクラス内およびその派生クラス内でアクセス可能
  • public:メンバはどこからでもアクセス可能
  • データアクセスの制御とカプセル化の維持に役立つ

クラス間の継承を実装する

このステップでは、C++ における継承について学びます。オブジェクト指向プログラミングの基本概念であり、既存のクラスを基に新しいクラスを作成することができます。

WebIDE で student.cpp ファイルを開き、継承を示すようにコードを変更します。

#include <iostream>
#include <string>

// 基底クラス
class Person {
protected:
    std::string name;
    int age;

public:
    // コンストラクタ
    Person(std::string personName, int personAge) {
        name = personName;
        age = personAge;
    }

    // 基本情報を表示するメソッド
    void displayInfo() {
        std::cout << "Name: " << name << std::endl;
        std::cout << "Age: " << age << std::endl;
    }
};

// 派生クラス:Student は Person から継承する
class Student : public Person {
private:
    double gpa;
    std::string major;

public:
    // 基底クラスのコンストラクタを呼び出すコンストラクタ
    Student(std::string studentName, int studentAge, double studentGPA, std::string studentMajor)
        : Person(studentName, studentAge) {
        gpa = studentGPA;
        major = studentMajor;
    }

    // Student に固有の追加メソッド
    void displayStudentInfo() {
        // 基底クラスのメソッドを呼び出す
        displayInfo();
        std::cout << "GPA: " << gpa << std::endl;
        std::cout << "Major: " << major << std::endl;
    }
};

// もう一つの派生クラス:Employee は Person から継承する
class Employee : public Person {
private:
    std::string company;
    double salary;

public:
    // 基底クラスのコンストラクタを呼び出すコンストラクタ
    Employee(std::string employeeName, int employeeAge, std::string employeeCompany, double employeeSalary)
        : Person(employeeName, employeeAge) {
        company = employeeCompany;
        salary = employeeSalary;
    }

    // Employee に固有の追加メソッド
    void displayEmployeeInfo() {
        // 基底クラスのメソッドを呼び出す
        displayInfo();
        std::cout << "Company: " << company << std::endl;
        std::cout << "Salary: $" << salary << std::endl;
    }
};

int main() {
    // 派生クラスのオブジェクトを作成する
    Student student("Alice Johnson", 20, 3.75, "Computer Science");
    std::cout << "Student Information:" << std::endl;
    student.displayStudentInfo();

    std::cout << "\n";

    Employee employee("Bob Smith", 35, "Tech Corp", 75000.0);
    std::cout << "Employee Information:" << std::endl;
    employee.displayEmployeeInfo();

    return 0;
}

プログラムをコンパイルして実行します。

g++ student.cpp -o student
./student

例の出力:

Student Information:
Name: Alice Johnson
Age: 20
GPA: 3.75
Major: Computer Science

Employee Information:
Name: Bob Smith
Age: 35
Company: Tech Corp
Salary: $75000

継承に関する要点:

  • 基底クラス (Person) には共通の属性が含まれる
  • 派生クラス (Student、Employee) は基底クラスから継承する
  • : public BaseClassName を使用して継承する
  • 派生クラスで新しい属性やメソッドを追加できる
  • 派生クラスで基底クラスのメソッドを使用できる

基底クラスのメソッドをオーバーライドする

このステップでは、C++ で基底クラスのメソッドをどのようにオーバーライドするかを学びます。これにより、派生クラスが基底クラスから継承したメソッドの独自の実装を提供できるようになります。

WebIDE で student.cpp ファイルを開き、メソッドのオーバーライドを示すようにコードを変更します。

#include <iostream>
#include <string>

class Animal {
protected:
    std::string name;

public:
    Animal(std::string animalName) : name(animalName) {}

    // Virtual キーワードにより、メソッドをオーバーライド可能にする
    virtual void makeSound() {
        std::cout << "Some generic animal sound" << std::endl;
    }

    // 情報を表示するための Virtual メソッド
    virtual void displayInfo() {
        std::cout << "Animal Name: " << name << std::endl;
    }
};

class Dog : public Animal {
private:
    std::string breed;

public:
    Dog(std::string dogName, std::string dogBreed)
        : Animal(dogName), breed(dogBreed) {}

    // makeSound メソッドをオーバーライド
    void makeSound() override {
        std::cout << "Woof! Woof!" << std::endl;
    }

    // displayInfo メソッドをオーバーライド
    void displayInfo() override {
        // まず基底クラスのメソッドを呼び出す
        Animal::displayInfo();
        std::cout << "Breed: " << breed << std::endl;
    }
};

class Cat : public Animal {
private:
    std::string color;

public:
    Cat(std::string catName, std::string catColor)
        : Animal(catName), color(catColor) {}

    // makeSound メソッドをオーバーライド
    void makeSound() override {
        std::cout << "Meow! Meow!" << std::endl;
    }

    // displayInfo メソッドをオーバーライド
    void displayInfo() override {
        // まず基底クラスのメソッドを呼び出す
        Animal::displayInfo();
        std::cout << "Color: " << color << std::endl;
    }
};

int main() {
    // 動物のオブジェクトを作成する
    Animal genericAnimal("Generic Animal");
    Dog myDog("Buddy", "Labrador");
    Cat myCat("Whiskers", "Orange");

    // ポリモーフィックな動作を示す
    std::cout << "Generic Animal:" << std::endl;
    genericAnimal.displayInfo();
    genericAnimal.makeSound();

    std::cout << "\nDog:" << std::endl;
    myDog.displayInfo();
    myDog.makeSound();

    std::cout << "\nCat:" << std::endl;
    myCat.displayInfo();
    myCat.makeSound();

    return 0;
}

プログラムをコンパイルして実行します。

g++ student.cpp -o student
./student

例の出力:

Generic Animal:
Animal Name: Generic Animal
Some generic animal sound

Dog:
Animal Name: Buddy
Breed: Labrador
Woof! Woof!

Cat:
Animal Name: Whiskers
Color: Orange
Meow! Meow!

メソッドのオーバーライドに関する要点:

  • オーバーライドを可能にするために、基底クラスで virtual キーワードを使用する
  • 派生クラスで override キーワードを使用して明示的にオーバーライドする
  • BaseClass::method() を使用して基底クラスのメソッドを呼び出せる
  • 同じメソッドに対して異なる実装を許す
  • ポリモーフィックな動作を可能にする

アクセス制御のためのフレンド関数を作成する

このステップでは、C++ におけるフレンド関数について学びます。フレンド関数は、外部関数や他のクラスがクラスのプライベートおよびプロテクテッドメンバにアクセスできるようにします。

WebIDE で student.cpp ファイルを開き、フレンド関数を示すようにコードを変更します。

#include <iostream>
#include <string>

class BankAccount {
private:
    std::string accountHolder;
    double balance;

    // フレンド関数を宣言する
    friend void displayAccountDetails(const BankAccount& account);
    friend class AccountManager;

public:
    // コンストラクタ
    BankAccount(std::string name, double initialBalance) {
        accountHolder = name;
        balance = initialBalance;
    }

    // お金を預けるメソッド
    void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
        }
    }
};

// プライベートメンバにアクセスできるフレンド関数
void displayAccountDetails(const BankAccount& account) {
    std::cout << "Account Holder: " << account.accountHolder << std::endl;
    std::cout << "Current Balance: $" << account.balance << std::endl;
}

// プライベートメンバにアクセスできるフレンドクラス
class AccountManager {
public:
    // BankAccount のプライベートメンバにアクセスできるメソッド
    void transferFunds(BankAccount& from, BankAccount& to, double amount) {
        if (from.balance >= amount) {
            from.balance -= amount;
            to.balance += amount;
            std::cout << "Transfer successful!" << std::endl;
        } else {
            std::cout << "Insufficient funds!" << std::endl;
        }
    }
};

int main() {
    // 銀行口座を作成する
    BankAccount account1("Alice Johnson", 1000.0);
    BankAccount account2("Bob Smith", 500.0);

    // フレンド関数を使って口座の詳細を表示する
    std::cout << "Account 1 Details:" << std::endl;
    displayAccountDetails(account1);

    std::cout << "\nAccount 2 Details:" << std::endl;
    displayAccountDetails(account2);

    // フレンドクラスを使って資金を振り替える
    AccountManager manager;
    std::cout << "\nTransferring $200 from Alice to Bob:" << std::endl;
    manager.transferFunds(account1, account2, 200.0);

    std::cout << "\nUpdated Account Details:" << std::endl;
    displayAccountDetails(account1);
    displayAccountDetails(account2);

    return 0;
}

プログラムをコンパイルして実行します。

g++ student.cpp -o student
./student

例の出力:

Account 1 Details:
Account Holder: Alice Johnson
Current Balance: $1000

Account 2 Details:
Account Holder: Bob Smith
Current Balance: $500

Transferring $200 from Alice to Bob:
Transfer successful!

Updated Account Details:
Account Holder: Alice Johnson
Current Balance: $800
Account Holder: Bob Smith
Current Balance: $700

フレンド関数に関する要点:

  • friend キーワードを使って宣言する
  • クラスのプライベートおよびプロテクテッドメンバにアクセスできる
  • クラス定義の中で宣言する
  • 個々の関数またはクラス全体にすることができる
  • カプセル化を破壊するので、控えめに使用する

静的メンバとメソッドを使用する

このステップでは、C++ における静的メンバとメソッドについて学びます。これらは、クラスのすべてのインスタンスで共有され、個々のオブジェクトではなくクラス自体に属します。

WebIDE で student.cpp ファイルを開き、静的メンバとメソッドを示すようにコードを変更します。

#include <iostream>
#include <string>

class University {
private:
    std::string name;
    static int totalStudents;  // 静的メンバ変数
    static double totalTuition;  // もう一つの静的メンバ変数

public:
    // コンストラクタ
    University(std::string universityName) : name(universityName) {}

    // 学生を追加するメソッド
    void addStudents(int count) {
        totalStudents += count;
    }

    // 授業料を追加するメソッド
    void addTuition(double amount) {
        totalTuition += amount;
    }

    // 全大学の学生数を表示する静的メソッド
    static void displayTotalStudents() {
        std::cout << "Total Students Across All Universities: "
                  << totalStudents << std::endl;
    }

    // 収集された授業料の合計を表示する静的メソッド
    static void displayTotalTuition() {
        std::cout << "Total Tuition Collected: $"
                  << totalTuition << std::endl;
    }

    // 平均授業料を計算する静的メソッド
    static double calculateAverageTuition() {
        return (totalStudents > 0)?
               (totalTuition / totalStudents) : 0.0;
    }
};

// クラスの外で静的メンバ変数を初期化する
int University::totalStudents = 0;
double University::totalTuition = 0.0;

int main() {
    // 大学のオブジェクトを作成する
    University harvard("Harvard University");
    University mit("MIT");
    University stanford("Stanford University");

    // 学生と授業料を追加する
    harvard.addStudents(5000);
    harvard.addTuition(75000000.0);

    mit.addStudents(4500);
    mit.addTuition(65000000.0);

    stanford.addStudents(4200);
    stanford.addTuition(60000000.0);

    // クラスに直接静的メソッドを呼び出す
    std::cout << "University Statistics:" << std::endl;
    University::displayTotalStudents();
    University::displayTotalTuition();

    // 平均授業料を計算して表示する
    std::cout << "Average Tuition per Student: $"
              << University::calculateAverageTuition() << std::endl;

    return 0;
}

プログラムをコンパイルして実行します。

g++ student.cpp -o student
./student

例の出力:

University Statistics:
Total Students Across All Universities: 13700
Total Tuition Collected: $2e+08
Average Tuition per Student: $14598.5

静的メンバとメソッドに関する要点:

  • クラスのすべてのインスタンスで共有される
  • static キーワードを使用して宣言される
  • オブジェクトを作成せずにアクセスできる
  • 個々のオブジェクトではなくクラスに属する
  • クラス全体の情報を追跡するのに役立つ

まとめ

この実験では、オブジェクト指向プログラミングにおける重要な概念である、プライベートなデータメンバを持つクラスを定義する方法を学びました。プライベートなデータメンバは、オブジェクトの内部状態をカプセル化して保護するのに役立ちます。また、プライベートなデータメンバへの制御されたアクセスを可能にするパブリックなメンバ関数の重要性についても学びました。これにより、データの整合性と制御が維持されます。さらに、コンストラクタ、デストラクタ、アクセス指定子、継承、メソッドのオーバーライド、フレンド関数、および静的メンバとメソッドの使用方法を検討しました。これらはすべて、C++ におけるオブジェクト指向プログラミングの基本原理です。