본문 바로가기
프로그래밍

[C++] 명품 c++ 프로그래밍 실습 5장 12번

by 엽기토기 2020. 12. 23.
반응형

문제 쓰기 귀찮.... 이것도 두번째 레포트 과제였습니다.

----------------------------------------------------------------------------------------------------------------------
(1)번

<12(1)_class.h>

#pragma once
class Dept {
	int size; //scores 배열의 크기
	int* scores; //동적 할당 받을 정수 배열의 주소
public:
	Dept(int size) { //생성자
		this->size = size;
		scores = new int[size];
	}
	Dept(Dept&dept);//복사 생성자
	~Dept() { delete[]scores; }; //소멸자
	int getSize() { return size; } //size 리턴
	void read();//size 만큼 키보드에서 정수를 읽어 scores 배열에 저장
	bool isOver60(int index);
//index의 학생의 성적이 60 이상이면 true 리턴
};

 

<12(1)_imp.cpp>

#include <iostream>
#include "12(1)_class.h"
using namespace std;

void Dept::read() {
	for (int i = 0; i < size; i++) { //size 개수
		cin >> scores[i]; //성적을 score배열에 입력
	}
}
bool Dept::isOver60(int index) {
	if (scores[index] > 60)
		return true; // 성적이 60이상이면 true리턴
	else
		return false; //아니면 false리턴
}
Dept::Dept(Dept&dept) { //복사 생성자 구현
	this->size = dept.size; //size 복사
	scores = new int[size];  //scores를 위한 동적 할당
	for (int i = 0; i < size; i++) {  //size만큼
		this->scores[i] = dept.scores[i]; //배열 원소 복사
	}
}

 

<12(1)_main.cpp>

#include <iostream>
#include "12(1)_class.h"
using namespace std;

int countPass(Dept dept) { 
//dept 학과에 60점 이상으로 통과하는 학생의 수 리턴
	int count = 0; //count 0 초기화
	for (int i = 0; i < dept.getSize(); i++) { 
//size만큼 for문 돌리고 count
		if (dept.isOver60(i)) count++; 
//60점 이상일때 ture ->카운트++
	}
	return count; //count 리턴
}
int main() {
	Dept com(10);//총 10명이 있는 학과 com size = 10
	com.read();
//총 10명의 학생들의 성적을 키보드로부터 읽어 scores 배열에 저장
	int n = countPass(com);
//com학과에 60점 이상으로 통과한 학생의 수를 리턴 , 복사생성자 호출
	cout << "60점 이상은" << n << "명\n";
}

 

<설명>
com 객체 생성 후 size 10 집어 넣음. scores 동적 메모리할당. read 함수로 가서, size 수 만큼 성적을 입력하여 scores 배열에 저장. 복사 생성자 호출 하여 size scores배열 복사. countPass에서, isOver60함수에서 아까 scores배열에 집어넣은 값이 60이상인지 확인하여 60이상이면 true를 리턴. true이면 count++. 그걸 for문으로 i=0 부터 10까지 돌림. 따라서 60점 이상인 수 리턴. 리턴된 값 n에 대입. 그리고 n 출력.


(2)번

int n = countPass(com); 에서 복사 생성자가 호출 됨. Dept(Dept& dept); 가 작성되어 있지 않으면 컴파일러에서는 자동으로 디폴트 복사 생성자를 만들어줌. 그런데, 디폴트 복사 생성자는 기본적으로 얕은 복사를 수행하여 com 객체의 scores와 디폴트 복사 생성자 객체의 scores는 같은 메모리를 가리키게 됨. 따라서 소멸자가 실행될 때, 디폴트 복사 생성자의 객체가 소멸하여 메모리를 반환하고, com 객체가 소멸될 때 동적메모리가 중복하여 해제하려고 하기 때문에 오류가 발생함. 따라서 (깊은)복사 생성자를 작성하여 깊은 복사를 수행시켜야 함.


(3)번

<12(3)_class.h>

#pragma once
class Dept {
	int size; //scores 배열의 크기
	int* scores; //동적 할당 받을 정수 배열의 주소
public:
	Dept(int size) { //생성자
		this->size = size;
		scores = new int[size];
	}
	~Dept() { delete[]scores; }; //소멸자
	int getSize() { return size; } //size 리턴
	void read();//size 만큼 키보드에서 정수를 읽어 scores 배열에 저장
	bool isOver60(int index);
//index의 학생의 성적이 60 이상이면 true 리턴
	int countPass();
};

 

<12(3)_imp.cpp>

#include <iostream>
#include "12(3)_class.h"
using namespace std;

void Dept::read() {
	for (int i = 0; i < size; i++) { //size 개수
		cin >> scores[i]; //성적을 score배열에 입력
	}
}
bool Dept::isOver60(int index) {
	if (scores[index] > 60)
		return true; // 성적이 60이상이면 true리턴
	else
		return false; //아니면 false리턴
}
int Dept::countPass() { //dept 학과에 60점 이상으로 통과하는 학생의 수 리턴
	int count = 0; //count 0 초기화
	for (int i = 0; i < getSize(); i++) { //size만큼 for문 돌리고 count
		if (isOver60(i)) count++; //60점 이상일때 ture ->카운트++
	}
	return count; //count 리턴
}

 

<12(3)_main.cpp>

#include <iostream>
#include "12(3)_class.h"
using namespace std;

int main() {
	Dept com(10);//총 10명이 있는 학과 com size = 10
	com.read();//총 10명의 학생들의 성적을 키보드로부터 읽어 scores 배열에 저장
	int n = com.countPass();//com학과에 60점 이상으로 통과한 학생의 수를 리턴
	cout << "60점 이상은" << n << "명\n";
}

 

<설명>
복사생성자 제거, counterPass 멤버 함수 구현 (클래스 선언부에 선언하였음).

반응형