C++/클래스 헤더파일 분리와 상호참조

클래스 상호참조 (수강신청 예제)

(13530)

수강 신청을 위한 클래스들을 작성한다.
과목당 최대 학생 수는 무제한이며 최초 설정된 인원수로 포인터 배열을 동적 할당한다.

학생당 최대 과목 수는 10과목으로 한다.


<main.cpp>

#include <iostream>
#include "student.h"
#include "course.h"
using namespace std;
int main() {
	Student *s1, *s2, *s3;
	Course *c1, *c2, *c3;

	s1 = new Student("김길동", "60201111");
	s2 = new Student("이길동", "60202222");
	s3 = new Student("홍길동", "60203333");

	c1 = new Course("국어1", "1001", 20);  // 과목명, 과목번호, 제한인원
	c2 = new Course("영어1", "1002", 30);
	c3 = new Course("미적분", "1003", 30);

	c1->addStudent(s1);
	c1->addStudent(s2);
	c1->addStudent(s2);  // 같은 학생이 두번 더해지지 않도록 한다.
	c2->addStudent(s1);
	c2->addStudent(s2);
	c2->addStudent(s3);
	c3->addStudent(s1);
	c3->addStudent(s2);
	c3->addStudent(s3);
	c3->dropStudent(s1);  // 수강 철회

	c1->info();  // 과목명, 과목 번호, 학생수,  수강생의 이름과 학번 전부
	c2->info();
	c3->info();

	s1->info();  // 학생명, 학번,  수강과목의 과목명 과목번호
	s2->info();
	s3->info();

	cout << "---- after delete ---------- " << endl;
	delete s2;  // 소멸자를 잘 만들어 주어야 한다.
	c1->info();
    
	return 0;
}
더보기

/* 과제로는 이정도 밖에 구현하지 못했다. 그땐 너무 어려웠음 (물론 지금도) */

//Student *s1, *s2, *s3;
//Course *c1, *c2, *c3;
//s1 = new Student("김길동", "60201111");
//s2 = new Student("이길동", "60202222");
//s3 = new Student("홍길동", "60203333");
//c1 = new Course("국어1", "1001", 20);  // 과목명, 과목번호, 제한인원
//c2 = new Course("영어1", "1002", 30);
//c3 = new Course("미적분", "1003", 30);

//c1->addStudent(s1);
//c1->addStudent(s2);
//c1->addStudent(s2);  // 같은 학생이 두번 더해지지 않도록 한다.
//c2->addStudent(s1);
//c2->addStudent(s2);
//c2->addStudent(s3);
//c3->addStudent(s1);
//c3->addStudent(s2);
//c3->addStudent(s3);
////c3->dropStudent(s1);  // 수강 철회

//c1->info();  // 과목명, 과목 번호, 학생수,  수강생의 이름과 학번 전부
//c2->info();
//c3->info();
//cout << "----------------------------------------------\n";
//s1->info();  // 학생명, 학번,  수강과목의 과목명 과목번호
//s2->info();
//s3->info();

<course.cpp> 

#include "course.h"
#include "student.h"
#include <iostream>
#include <string>
using namespace std;

Course::Course(string t, string n, int m) {
	title = t;
	cnum = n;
	max = m;
	s = new Student*[m]; //Student** s; [이중포인터??]
	cnt = 0; //생성자에서 초기화
}

void Course::addStudent(Student* ns) {
	int same = 0; //무슨 변수지??
	for (int i = 0; i < cnt; i++) {
		if (s[i] == ns) {
			same++;
		}
	}
	if (same == 0) {
		s[cnt] = ns;
		cnt++;
		ns->setCourse(this); //파라미터 this??
	}
}

void Course::dropStudent(Student *ds) {
	int find = 0;
	int i = 0;
	for (find = 0; find < cnt; find++) {
		if (s[find] == ds) {
			break;
		}
	} //삭제할 배열 요소의 위치 저장
	for (i = find; i < cnt; i++) {
		s[i] = s[i + 1];
	} //배열 앞으로 당겨서 다시 저장
	s[i] = NULL;
	cnt--; //왜?? ->학생수-1
	ds->outCourse(this);
}

void Course::info() {
	cout << "과목명: " << title << endl;
	cout << "과목 번호: " << cnum << endl;
	cout << "학생 수: " << cnt << endl;

	for (int i = 0; i < cnt; i++) {
		string name = s[i]->getname(); //수강생 이름
		string snum = s[i]->getnum(); //학번
		cout << "수강생 이름: " << name << " / 학번: " << snum << endl;
	}
	cout << endl;
}

string Course::getT() { //getter???
	return title;
}

string Course::getN() {
	return cnum;
}

void Course::delstu(Student* ms) {
	int find = 0;
	int i = 0;
	for (find = 0; find < cnt; find++) {
		if (s[find] == ms) {
			break;
		}
	} //반환할 학생이 배열 몇번째에 있는지 알아내기
	s[find] = NULL;
	for (i = find; i < cnt; i++) {
		s[i] = s[i + 1]; 
	} //앞으로 당겨서 저장
	cnt--;
}

<student.cpp>

#include "course.h"
#include "student.h"
#include <iostream>
#include <string>
using namespace std;

Student::Student(string s, string n) {
	name = s;
	num = n;
	cnt = 0;
}

void Student::setCourse(Course* c) {
	myc[cnt] = c;
	cnt++;
}

string Student::getname() {
	return name;
}

string Student::getnum() {
	return num;
}

void Student::info() {
	cout << "학생명: " << name << " / 학번: " << num << endl;
	for (int i = 0; i < cnt; i++) {
		string title;
		title = myc[i]->getT();
		string cnum;
		cnum = myc[i]->getN();

		cout << "과목명: " << title << " / 과목 번호: " << cnum << endl;
	}
	cout << endl;
}

void Student::outCourse(Course* c) {
	int find = 0;
	int i = 0;
	for (find = 0; find < cnt; find++) {
		if (myc[find] == c) {
			break;
		}
	} //삭제할 배열 요소의 위치 저장

	for (i = find; i < cnt; i++) {
		myc[i] = myc[i + 1];
	} //배열 앞으로 당겨서 다시 저장
	myc[i] = NULL;
	cnt--;
}

<course.h>

#ifndef COURSE_H
#define COURSE_H
#include <iostream>
using namespace std;

class Student;
class Course {
	private:
		string title; //과목명
		string cnum; //과목 번호
		int max; //제한 인원
		int cnt;
		Student** s;
	public:
		Course(string t, string n, int m);
		void addStudent(Student* ns);
		void dropStudent(Student* ds);
		void info();
		string getT();
		string getN();
		void delstu(Student *ms);
};

#endif

<student.h>

#ifndef STUDENT_H
#define STUDENT_H
using namespace std;

class Course;
class Student {
	private:
		string name; //학생명
		string num; //학번
		Course* myc[10]; //학생당 최대 과목 수는 10과목
		int cnt; //학생수
	public:
		Student(string s, string n);
		void setCourse(Course* c);
		string getname();
		string getnum();
		void info();
		void outCourse(Course* c);
		~Student();
};
#endif

<실행결과>

과목명: 국어1
과목 번호: 1001
학생 수: 2
수강생 이름: 김길동 / 학번: 60201111
수강생 이름: 이길동 / 학번: 60202222

과목명: 영어1
과목 번호: 1002
학생 수: 3
수강생 이름: 김길동 / 학번: 60201111
수강생 이름: 이길동 / 학번: 60202222
수강생 이름: 홍길동 / 학번: 60203333

과목명: 미적분
과목 번호: 1003
학생 수: 2
수강생 이름: 이길동 / 학번: 60202222
수강생 이름: 홍길동 / 학번: 60203333

학생명: 김길동 / 학번: 60201111
과목명: 국어1 / 과목 번호: 1001
과목명: 영어1 / 과목 번호: 1002

학생명: 이길동 / 학번: 60202222
과목명: 국어1 / 과목 번호: 1001
과목명: 영어1 / 과목 번호: 1002
과목명: 미적분 / 과목 번호: 1003

학생명: 홍길동 / 학번: 60203333
과목명: 영어1 / 과목 번호: 1002
과목명: 미적분 / 과목 번호: 1003

---- after delete ----------
과목명: 국어1
과목 번호: 1001
학생 수: 1
수강생 이름: 김길동 / 학번: 60201111