본문 바로가기
2CHAECHAE 학교생활/객체지향프로그래밍(C++)

[ 객체지향프로그래밍(C++) 7주차 ② ]

by 2CHAE._.EUN 2022. 4. 16.

[ 7주차 - 2 ]

 

클래스에 배열 선언하기

 

클래스 객체들도 배열로 선언할 수 있다. resolution은 width와 height가 low, medium, high 중 무엇인지

enum형을 선언해주고 3 값중 하나를 저장해준다.

 

#include <iostream>
using namespace std;

enum resolution { low, medium, high };

class display {
private:
	int width; 
	int height;
	resolution res; //width, height가 low,medium,high인지 확인
public:
	void set_dim(int w, int h) { 
		width = w; height = h;
	}
	void get_dim(int& w, int& h) {
		w = width; h = height;
	}
	void set_res(resolution r) {
		res = r;
	}
	resolution get_res() {
		return res;
	}
};

char names[3][7] = { "low", "medium","high" };

int main() {

	display display_mode[3];
	int i, w, h;
	display_mode[0].set_res(low);
	display_mode[0].set_dim(640, 480);
	display_mode[1].set_res(medium);
	display_mode[1].set_dim(800, 600);
	display_mode[2].set_res(high);
	display_mode[2].set_dim(1600, 1200);

	cout << "Available display modes:\n\n";
	for (i = 0; i < 3; i++) {
		cout << names[display_mode[i].get_res()] << " : ";
		display_mode[i].get_dim(w, h);
		cout << w << " by " << h << "\n";
	}

	return 0;

}

// Available display modes:
//
//low : 640 by 480
//medium : 800 by 600
//high : 1600 by 1200

 

names에는 3개의 최대 7자리인 문자열 배열이 들어간다. 

 

 

객체에 대한 포인터

 

[ 객체 접근 방법 ]

 

1. 객체 자체를 사용 : 도트 연산자 사용

2. 객체에 대한 포인터 사용 : 화살표 연산자 사용

   - 객체에 대한 포인터가 증가되거나 감소할 때 다음 객체를 가리키도록 증가하거나 감소한다.

   - & 연산자를 사용하여 객체의 주소를 얻어낸다.

 

#include <iostream>
using namespace std;

class P_example{
private:
	int num;
public:
	void set_num(int val) {
		num = val;
	}
	void show_num();
};

void P_example::show_num() {
	cout << num << "\n";
}

int main() {

	P_example ob[2], * p; 
	
	//객체를 직접 접근한다.
	ob[0].set_num(10);
	ob[1].set_num(20);

	//첫번째 원소에 대한 포인터를 얻는다.
	p = &ob[0];
	//포인터를 이용하여 ob[0]의 값을 보여준다.
	p->show_num();
	p++; // 다음 객체로 전진한다.

	// 포인터를 이옹하여 ob[1]의 값을 보여준다.
	p->show_num();
	p--; // 이전 객체로 후퇴한다.

	//다시 ob[0]의 값을 보여준다.
	p->show_num();

	return 0;

}

//10
//20
//10

 

p 포인터 변수는 P_example 클래스 형이기 때문에 p에는 P_example 객체들의 주소만 저장이 되야한다. 다른

자료형의 객체들의 주소가 들어가면 안된다.

 

p에 ob[0]의 주소가 들어있을 경우 p.show_num()이나 p->show_num()이나 같다. 

p++는 실제로 p에는 ob[0]의 주소가 들어있기 때문에 +1이 되는 것이 아니라 P_example 객체가 가진 메모리

양만큼의 p의 주소에 더해진다. 그래서 ob[1] 객체를 가리키게 된다. 

 

즉 클래스 객체에 접근하기 위해서 포인터 변수를 사용할 수 있고 포인터 변수에 ++를 하게 된다면 +1/-1이 아니라

해당 클래스의 객체가 차지하고 있는 메모리 크기만큼 더해지거나 빼진다.

 

 

queue 클래스 선언

 

queue는 배열에 삽입되는 객체가 차례대로 저장이 되었다가 삭제할 때는 제일 먼저 삽입된 객체가 제일 먼저 삭제되는

First In First Out의 방식으로 데이터를 저장하는 자료구조이다.

 

#include <iostream>
using namespace std;

class queue {
// private 생략 가능
	int q[100];
	int sloc, rloc; //sloc : 가장 최근에 삽입 index / rloc : 가장 최근에 삭제 index
public:
	queue(); //생성자
	~queue(); //소멸자
	void qput(int i); // 삽입
	int qget(); // 삭제
};

// 생성자
queue::queue() {
	sloc = rloc = -1; // 아무 데이터도 삽입/삭제되지 않았다.
	cout << "Queue initialized.\n";
}

// 소멸자
queue::~queue() {
	cout << "Queue destroyed.\n";
}

void queue::qput(int i) {
	if (sloc == 99) {
		cout << "Queue is full.\n";
		return;
	}
	sloc++;
	q[sloc] = i;
}

int queue::qget() {
	if (rloc == sloc) { // queue가 비워져있다.
		cout << "Queue Underflow.\n.";
		return 0;
	}
	rloc++;
	return q[rloc];
}

int main() {

	queue a, b; 
	a.qput(10);
	b.qput(19);
	a.qput(20);
	b.qput(1);
	cout << a.qget() << " ";
	cout << a.qget() << " ";
	cout << b.qget() << " ";
	cout << b.qget() << "\n";

	return 0;

}

//Queue initialized.
//Queue initialized.
//10 20 19 1
//Queue destroyed.
//Queue destroyed.

 

 

클래스 멤버 배열의 동적 생성 ( queue 클래스 )

 

queue 클래스의 객체마다 저장하고자 하는 데이터의 크기를 다르게 설정해서 메모리 낭비를 방지하기 위해

포인터 변수를 사용해서 생성자 함수에서 동적 할당을 이용해서 queue를 선언할 수 있다. 동적 할당 하고자 하는

배열의 크기를 생성자 함수의 파라미터로 전달하면 된다.

 

#include <iostream>
using namespace std;

class queue {
private:
	int* q;
	int size;
	int sloc, rloc; //sloc : 가장 최근에 삽입 index / rloc : 가장 최근에 삭제 index
public:
	queue(int n); //생성자
	~queue(); //소멸자
	void qput(int i); // 삽입
	int qget(); // 삭제
};
 
// 생성자
queue::queue(int n = 100) {
	sloc = rloc = -1; // 아무 데이터도 삽입/삭제되지 않았다.
	size = n;
	q = new int[size]; // 동적 배열 할당
	cout << "Queue initialized.\n";
}

// 소멸자
queue::~queue() {
	cout << "Queue destroyed.\n";
}

void queue::qput(int i) {
	if (sloc == (size-1)) {
		cout << "Queue is full.\n";
		return;
	}
	sloc++;
	q[sloc] = i;
}

int queue::qget() {
	if (rloc == sloc) {
		cout << "Queue Underflow.\n.";
		return 0;
	}
	rloc++;
	return q[rloc];
}

int main() {

	queue a(50); // a.queue 크기는 50
	queue b; // b.queue 크기는 100
	a.qput(10);
	b.qput(19);
	a.qput(20);
	b.qput(1);
	cout << a.qget() << " ";
	cout << a.qget() << " ";
	cout << b.qget() << " ";
	cout << b.qget() << "\n";

	return 0;

}

 

 

실습 문제

 

queue 클래스에 두 개의 멤버함수를 추가하고 실행하기

1. 큐 클래스의 큐에 들어있는 원소들 중에서 가장 큰 값을 반환하는 멤버 함수를 작성하기 ( int queue::max() )

2. 큐 클래스의 큐에 들어있는 원소들을 매개변수의 수만큼 뒤에서 부터 출력하는 멤버 함수를 작성하라

   ( void queue::reverse_print(int num) )

 

< main 함수 >

 

1. queue a(20);

2. 6개의 값을 큐에 삽입 a.qput()

3. cout << a.max();

4. a.reverse_print(4);