404 Not Found

404 Not Found


nginx

演習:オブジェクト指向設計

[これまでの]35[課]で、[私たちは]C++[のあらゆる側面]を学びました。

[今]、[まさに][総合的に活用する][時]です。

[この授業では]、[私たちは][完全な学生管理システム]を[要件定義から]code[実装]まで[一通り作り上げ]、[本格的なソフトウェア開発を体験]します。


1. プロジェクト[要件分析]

(1) 1.1 [機能要件]

[私たちが実現しようとしている学生管理システム]は、[以下の機能を備えています]:

[機能モジュール] [具体的な機能]
[学生管理] [追加]、[削除]、[編集]、[学生の検索]
[成績管理] [成績入力]、[平均点の算出]、[順位]
[データの永続化] [ファイルへの保存]、[ファイルからの読み込み]
[ユーザーインターフェース] [メニュー駆動型のコンソールインターフェース]

(2) 1.2 クラス[の設計]

[要件に基づき]、[以下の]クラスを設計する必要があります:

TEXT
Student()
 ↑ 
UndergraduateStudent()
GraduateStudent()

Course()
Grade()

ManagementSystem()
 - vector<Student*> students
 - vectorCourse courses


2. [基本バージョンの実装]

(1) 2.1 [学生]クラス[設計]

例:[学生]クラス[基礎版] (難易度 ⭐⭐)

CPP
#include iostream
#include string
#include vector

// ...
class Student {
protected:
 std::string id; // ...
 std::string name; // ...
 int age; // ...
 std::string major; // ...

public:
 // ...
 Student(const std::string& id, const std::string& name, int age, const std::string& major)
 : id(id), name(name), age(age), major(major) {}
 
 //:
 virtual void display() const {
 std::cout << ":" << id << std::endl;
 std::cout << ":" << name << std::endl;
 std::cout << ":" << age << std::endl;
 std::cout << ":" << major << std::endl;
 }
 
 // ...
 virtual ~Student() {}
 
 // Getter
 std::string getId() const { return id; }
 std::string getName() const { return name; }
};

// ...
class UndergraduateStudent : public Student {
private:
 int year; // (1-4)

public:
 UndergraduateStudent(const std::string& id, const std::string& name, 
 int age, const std::string& major, int year)
 : Student(id, name, age, major), year(year) {}
 
 void display() const override {
 Student::display();
 std::cout << ":" << year << "..." << std::endl;
 std::cout << ":" << std::endl;
 }
};

// ...
class GraduateStudent : public Student {
private:
 std::string advisor; // ...

public:
 GraduateStudent(const std::string& id, const std::string& name,
 int age, const std::string& major, const std::string& advisor)
 : Student(id, name, age, major), advisor(advisor) {}
 
 void display() const override {
 Student::display();
 std::cout << ":" << advisor << std::endl;
 std::cout << ":" << std::endl;
 }
};

(2) 2.2 [管理システム]クラス

例:[管理システム ベーシック版] (難易度 ⭐⭐⭐)

▶ サンプル 1: STLコンテナ[使用] (難易度 ⭐)

CPP
class ManagementSystem {
private:
 std::vector<Student*> students; // ()

public:
 // ...
 void addStudent(Student* student) {
 students.push_back(student);
 std::cout << "!" << std::endl;
 }
 
 // ...
 Student* findStudent(const std::string& id) {
 for (auto s : students) {
 if (s->getId() == id) {
 return s;
 }
 }
 return nullptr;
 }
 
 // ...
 void displayAll() const {
 if (students.empty()) {
 std::cout << "..." << std::endl;
 return;
 }
 
 for (auto s : students) {
 s->display();
 std::cout << "-------------------" << std::endl;
 }
 }
 
 //:
 ~ManagementSystem() {
 for (auto s : students) {
 delete s;
 }
 }
};

// ...
int main() {
 ManagementSystem sys;
 
 // ...
 sys.addStudent(new UndergraduateStudent("001", "...", 20, "...", 3));
 sys.addStudent(new GraduateStudent("002", "...", 24, "...", "..."));
 
 // ...
 sys.displayAll();
 
 return 0;
}
▶ 試してみよう

[実行結果]:

-------------------:002::24:::
-------------------


3. [完全版の実装]

(1) 3.1 [機能の追加]

[現在]、[システムにさらなる機能を追加しています]:

[機能] [実装方法]
[学生を削除] [学籍番号で削除]
[情報の変更] [学籍番号で検索]、[変更]
[成績管理] [成績の追加]クラス
ファイル[保存] [用] ofstream [書]ファイル
ファイル[読み込み] ifstream を使用して [ファイル]を読み込む

(2) 3.2 [成績]クラス[設計]

CPP
// ...
### (3) ▶ 2:(⭐)

class Grade {
private:
 std::string courseId; // ID
 std::string courseName; // ...
 double score; // points

public:
 Grade(const std::string& courseId, const std::string& courseName, double score)
 : courseId(courseId), courseName(courseName), score(score) {}
 
 void display() const {
 std::cout << courseName << ":" << score << "points" << std::endl;
 }
 
 double getScore() const { return score; }
};

// ...
class Student {
 // ... ...
 std::vectorGrade grades; // ...

public:
 void addGrade(const Grade& grade) {
 grades.push_back(grade);
 }
 
 void displayGrades() const {
 if (grades.empty()) {
 std::cout << "..." << std::endl;
 return;
 }
 
 std::cout << name << ":" << std::endl;
 for (const auto& g : grades) {
 g.display();
 }
 }
 
 double getAverage() const {
 if (grades.empty()) return 0.0;
 
 double sum = 0;
 for (const auto& g : grades) {
 sum += g.getScore();
 }
 return sum / grades.size();
 }
};

(3) 3.3 ファイル[操作]

[学生情報を保存するファイル:]

CPP
void saveToFile(const std::string& filename) {
 std::ofstream file(filename);
 if (!file) {
 std::cout << "..." << std::endl;
 return;
 }
 
 for (auto s : students) {
 file << s->getId() << ","
 << s->getName() << ","
 << s->getAge() << std::endl;
 }
 
 file.close();
 std::cout << "!" << std::endl;
}

[ファイルから]読み込み:

CPP
void loadFromFile(const std::string& filename) {
 std::ifstream file(filename);
 if (!file) {
 std::cout << "..." << std::endl;
 return;
 }
 
 std::string id, name, ageStr;
 while (std::getline(file, id, ',')) {
 std::getline(file, name, ',');
 std::getline(file, ageStr);
 int age = std::stoi(ageStr);
 
 // (,points/)
 students.push_back(new UndergraduateStudent(id, name, age, "...", 1));
 }
 
 file.close();
 std::cout << "!" << std::endl;
}


4. [メニュー画面の実装]

(1) 4.1 [メインメニュー]

CPP
void showMenu() {
 std::cout << "\n===== =====" << std::endl;
 std::cout << "1." << std::endl;
 std::cout << "2." << std::endl;
 std::cout << "3." << std::endl;
 std::cout << "4." << std::endl;
 std::cout << "5." << std::endl;
 std::cout << "6." << std::endl;
 std::cout << "0." << std::endl;
 std::cout << "========================" << std::endl;
 std::cout << ":";
}

int main() {
 ManagementSystem sys;
 int choice;
 
 do {
 showMenu();
 std::cin >> choice;
 
 switch (choice) {
 case 1:
 // ...
 break;
 case 2:
 // ...
 break;
 case 3:
 sys.displayAll();
 break;
 case 0:
 std::cout << "!" << std::endl;
 break;
 default:
 std::cout << "..." << std::endl;
 }
 } while (choice != 0);
 
 return 0;
}


5. プロジェクト[拡張提案]

(1) 5.1 [機能拡張]

[機能] [難易度] [説明]
[成績統計] ⭐⭐ [平均点の算出]、[順位]
[データ検証] ⭐⭐ [チェック]入力[有効性]
例外処理 ⭐⭐⭐ [用] try-catch [処理]エラー
[グラフィカルユーザーインターフェース] ⭐⭐⭐⭐ [Qt]または[wxWidgets]を使用
[データベース] ⭐⭐⭐⭐ [SQLiteまたは]MySQL

(2) 5.2 コードの最適化

最適化[点] [説明]
スマートポインタ [使用] unique_ptr [メモリ管理]
const[正しさ] [可能な限り使用する] const
例外処理 [用] try-catch [処理]fileerror
演算子のオーバーロード オーバーロード << [出力用]

❓ よくある質問

Q:[なぜ]ポインタ[を使って学生を格納する]のか? A:[ポリモーフィズムを実現するため]。[もし] vectorStudent を使えば、[オブジェクトのスライシングが]発生し、[基底クラスのメソッドしか呼び出せなくなる]。


Q:メモリリーク[どうすればいいですか]? A:スマートポインタ(unique_ptr)を使ってメモリを[自動管理]すれば、[手動で] deleteする必要はありません。


Q:ファイル形式はどのように設計すればよいですか? A:[以下の形式が利用可能です]: - CSV形式:[シンプル]ですが、[機能に制限があります] - JSON形式:[機能豊富]ですが、[サードパーティ製ライブラリが必要です] - [バイナリ形式]:[効率が良い]ですが、[人間が読み取れません]


Q [中国語の文字はどう処理すればよいですか]?
A C++は[中国語への対応が不十分]です。[以下の方法をお勧めします]: - wstring + wcout [を使用する] - [サードパーティ製ライブラリ]([例:]iconv)[を使用する] - [ピンイン]または[英語]のみを保存する

📖 まとめ

[知識ポイント] [要点]
class[設計] 基底クラス + 派生クラス,[体現]継承
多態性 [ポインタ/参照]による仮想関数の呼び出し
ファイル[操作] ofstream [書き込み],ifstream [読み取り]
メモリ[管理] デストラクタ[解放]メモリ([または]スマートポインタ)
[メニュー画面] do-while + switch

[学習のヒント]:


📝 練習問題

  1. 初心者(難易度 ⭐):[Bookクラス([書名]、[著者]、[価格])を定義し、3つのオブジェクトを[作成]して、[それらの属性]を出力する。

  2. **中級(難易度 ⭐⭐):[継承]体系を実装する:Shape(基底クラス、純粋仮想関数 area())→ Circle [および] Rectangle の派生クラス。[多態性]を利用して area を呼び出す。

  3. **上級(難易度 ⭐⭐⭐):[「オブザーバーパターン」を実装する]:Subjectクラスは[オブザーバーのリストを保持し]、オブザーバーは[抽象]基底クラスである。[Subjectの状態が変化した際、すべての]オブザーバーに通知する。



フェーズ5 [終了]![次へ]:フェーズ6(STL[上級])

Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%