강좌 첫화면으로 최근 글 보기(Post)
갈래별로 보기 categories




  3.13.클래스란 무엇인가?



3.13.클래스란 무엇인가?


3.13.1.클래스는 변수의 집합체입니다.


C++에서 클래스는 객체와 객체를 다루는 함수로 구성되어 있습니다.

이제 객체가 수학점수 자체를 말한다는 정도는 이해하셨을 것으로 보고 객체를 활용하기 위한 구체적인 방법론을 알아보도록 하겠습니다. C++에서 클래스를 이용하여 강력한 객체를 선언할 수 있습니다. 또한 클래스를 이용할 때 객체지향 방식의 프로그램 구현이 쉽습니다.
C++의 원래 이름이 C with the Class라는 점은 몇 번에 걸쳐서 말씀드렸습니다. 다시 말해 클래스를 빼놓고는 C++의 장점을 논의할 수 없다는 뜻입니다.

앞서 말씀드린 것처럼 클래스는 배열에서 발전된 형태의 자료형입니다. 배열과 다른 점은 다양한 형태의 자료를 포함할 수 있다는 점입니다. 성적관리 프로그램을 예로 들겠습니다. 데이터베이스 프로그램이나 스프레드시트 프로그램을 이용할 경우 성적관리 프로그램의 기본적인 항목은 다음과 같이 결정됩니다.

**보기: 성적 관리 프로그램의 항목과 입력될 자료 내용들


학생 이름: 김중태
학생 번호: 33
국어 점수: 100
수학 점수: 80
영어 점수: 70
합계 점수: 250
평균 점수: 83.3
석차 : 9

이상의 항목을 위해서 각 항목별로 사용될 자료형은 다음과 같습니다.

**보기: 성적 관리 프로그램의 항목별 자료형


학생 이름: 이름을 입력할 것이므로 문자열상수(문자배열)
학생 번호: 0부터 100까지의 숫자를 사용하므로 정수형
국어 점수: 0부터 100까지의 숫자를 사용하므로 정수형
수학 점수: 0부터 100까지의 숫자를 사용하므로 정수형
영어 점수: 0부터 100까지의 숫자를 사용하므로 정수형
합계 점수: 0부터 300까지의 숫자를 사용하므로 정수형
평균 점수: 평균점수는 소수점으로 계산되므로 실수형
석차 : 0부터 100까지의 숫자를 사용하므로 정수형

보기를 통해 알 수 있는 것처럼 학생이름은 문자열을 이용하고, 평균 점수는 실수형, 나머지는 정수형 자료로 입력받아 사용하면 됩니다. 이것이 성적관리 프로그램에서 사용할 객체의 자료형입니다.
그러면 이것으로 객체의 구성이 끝난 것일까요? 아닙니다. 각 객체를 외부에서 활용하려면 입출력에 관항 방법, 다시 말해서 입출력 함수를 만들어야 합니다. 함수는 다음과 같은 것이 필요합니다.

**보기: 성적 관리 프로그램의 항목별 자료형


학생 이름, 학생 번호, 국영수 점수를 입력받을 수 있는 함수
입력받은 국영수 점수를 이용하여 합계, 평균, 석차를 내 각 항목에 기록하는 함수
각 항목을 보여주는 함수
이미 기록된 이름과번호, 국영수 점수를 고치기 위한 함수

자료와 함수로 구성된 구조를 캡슐(capsule) 구조라고 합니다.

따라서 성적관리 프로그램의 클래스는 다음과 같은 형태로 구성됩니다.

**보기: 성적 관리 프로그램의 클래스 구성 내용


- 객체 항목과 자료형

학생 이름: 김중태 (char name[];)
학생 번호: 33 (int no;)
국어 점수: 100 (int kor;)
수학 점수: 80 (int math;)
영어 점수: 70 (int eng;)
합계 점수: 250 (int total;)
평균 점수: 83.3 (float average;)
석차 : 9 (int level;)

- 객체를 외부의 프로그램과 연결시키기 위해 사용하는 함수

자료를 입력받는 함수 indata()
합계를 내는 함수 maketot()
평균 내는 함수 makeav()
석차를 내는 함수 makelev()
항목에 기록하는 함수 writedata()
항목을 보여주는 함수 dispdata()
......

보기를 통해서 알 수 있는 것처럼 C++에서 클래스는 객체와 객체를 다루는 함수로 구성되어 있습니다. 이런 구조를 캡슐(capsule) 구조라고 하며, 객체인 데이터와 함수를 하나로 묶는 방법을 캡슐화(encapsulation)라고 합니다.

**요약: C++에서 클래스는 자료와 함수로 구성된 캡슐구조를 가집니다.


3.13.2.캡슐 구조의 장점


캡슐구조는 보여주기 싫은 정보를 감출 수 있으며, 프로그램의 오류를 줄이는 장점이 있습니다.

클래스의 구조는 자료와 함수를 동시에 가진 캡슐 모양을 가지고 있습니다. 약국에서 주는 알약과 같은 모양입니다.

자료
함수

이처럼 클래스는 자료와 함수로 구성된 새로운 형태의 자료형입니다. 그동안 우리가 배운 정수형, 문자형, 실수형과는 다른 새로운 형태의 복합적인 구조를 가진 자료형이라고 이해하시면 됩니다.

클래스가 캡슐구조를 가짐으로써 얻는 장점은 여러 가지가 있습니다만 대표적인 장점은 객체를 잘못 다룰 염려가 없다는 점과 프로그램을 짤 때 자신이 다룰 클래스의 구조만 이해하면 된다는 점입니다. 또한 불필요한 정보를 남에게 보이지 않고 감출 수 있다는 점도 장점입니다.

예를 들겠습니다. 지금까지 저희가 연습한 예제는 모두 외부에 있는 함수가 직접 자료(=객체)를 다루었습니다. 이때 함수가 다른 함수를 부르거나 함수가 변수나 상수와 같은 자료를 부르는 과정을 호출한다고 말합니다. 따라서 지금까지의 프로그램은 다음과 같은 구조로 이루어졌습니다.

호출
함수 ──── 데이터

따라서 함수를 만든 사람이 직접 데이터를 조작해야 하므로 모든 데이터를 함수를 만드는 사람 즉, 프로그래머에게 공개되어야 합니다. 따라서 어떤 기업에서 중요한 기업내 인사기록이 있고 외부에 인사기록 관리 프로그램을 만들어달라고 의뢰한다고 합시다. 이 경우 과거의 방법은 인사기록 자료를 외부 업체에게 공개할 수밖에 없었습니다.

그러나 캡슐화된 형태로 자료를 기록해두었다면 달라집니다. 외부 함수는 클래스 안의 함수를 통해서만 자료를 볼 수 있습니다. 따라서 직접적으로 자료를 건드리거나 보지 못합니다. 즉 다음과 같은 형태로 이루어집니다.


┌───────────────────────┐
호출 │ 호출 │
함수 ───┤ 클래스 안의 함수 ------- 클래스 안의 자료 │
└───────────────────────┘

캡슐화되면 외부함수가 공개된 자료만 다룰 수 있게 됩니다.

이처럼 외부의 함수는 이제 클래스 안의 함수를 통해서 간접적으로 클래스 안의 자료를 참고할 수 있습니다. 따라서 감추고 싶은 자료는 클래스 안의 함수로만 다루고 외부로 보여주고 싶은 자료만 클래스 함수를 거쳐서 외부로 보여줄 수 있습니다.
그러므로 클래스 안의 자료는 다음과 같은 구조로 이루어져 있습니다.

┌───────────────────────────────┐
호출 │ │
함수 ───┤ 클래스 안의 공개영역(public) 자료 │
├───────────────────────────────┤
호출 │ 호출 │
함수 ───┤ 클래스 안의 함수 ------- 클래스 안의 개인영역(private) 자료 │
└───────────────────────────────┘

그러니까 클래스 안의 개인영역 자료는 같은 클래스의 멤버 함수만이 호출하여 활용할 수 있으며 외부 함수는 직접적으로 활용할 수 없습니다. 다만 공개영역으로 공개한 부분은 외부함수에서 직접 제어할 수 있지만 그외 개인영역으로 지정된 자료는 클래스 멤버 함수를 통해서만 사용 가능합니다.
이런 구조가 가지는 장점은 첫번째로 외부에 공개하고 싶지 않은 영역의 자료를 감출 수 있다는 점입니다. 두번째로 클래스 안의 자료나 변수, 함수를 잘못 건드릴 일이 줄어든다는 점입니다.
예를 들어 클래스 안에서 회원번호로 no라는 변수를 선언했다고 합시다. 그리고 클래스 밖에서는 석차를 나타내기 위하여 또 다시 no라는 변수를 선언해 사용하더라도 클래스 안의 no에 영향을 미치지 않습니다. 그러나 클래스를 사용하지 않을 경우에는 회원번호인 변수 no를 석차를 나타내는 변수 no와 혼동하여 사용할 가능성이 매우 높으며 이럴 경우 엉뚱한 결과가 나옵니다.
때문에 캡슐구조를 가진 클래스는 외부의 함수로부터 자료를 보호할 수 있다는 점과 프로그램의 논리상 문제를 줄일 수 있다는 점, 객체지향 프로그램을 구현하기 쉽다는 장점을 가집니다.

**요약: 캡슐구조의 장점은 자료의 외부노출을 막을 수 있으며, 논리적인 오류를 줄일 수 있다는 점입니다.


3.13.3.클래스의 선언방법


class라는 키워드를 이용하여 클래스를 선언합니다.

이제 클래스의 개념을 배웠으니 실제로 클래스를 선언하고 사용하는 방법을 알아보겠습니다.
클래스는 다음과 같은 형식으로 선언합니다.

보기: 클래스의 선언 형식

class 클래스이름optin { 클래스멤버목록option} 객체이름option;

조금 복잡해보이지만 이 중에서 옵션인 클래스이름과 클래스멤버목록, 객체이름을 제외하면 결국 꼭 필요한 것은 키워드인 class와 {}; 뿐입니다. 나머지는 생략 가능합니다.


클래스를 선언할 때는 여러 가지 규칙에 따라야 합니다.

그리고 클래스를 선언할 때는 많은 규칙이 붙는데 그 중에서도 중요한 규칙은 다음과 같습니다. 그외 상세한 규칙이 많이 있는데 이들 규칙에 대해서는 나중에 기회날 때 다른 책을 통해서 설명드리고자 합니다.

- 클래스를 선언하는 키워드는 class이지만 struct도 사용할 수 있습니다. class를 이용하면 클래스멤버가 기본적으로 사적영역으로 선언되며, struct를 이용하면 클래스멤버가 기본적으로 공개영역으로 선언되는 차이가 있습니다. 가능한 키워드로는 class를 사용하는 것이 좋습니다.
- 클래스이름은 변수 이름처럼 아무렇게 정할 수 있습니다. 클래스이름을 생략할 수도 있는데 이럴 경우를 단일 객체(singleton objects)라고 합니다. 그러나 단일 객체를 선언할 때는 객체이름을 생략할 수 없습니다. 다시 말해서 클래스이름을 생략하면 객체이름을 꼭 적어야 하며, 객체이름을 생략하려면 클래스이름을 적어야 한다는 뜻입니다. 둘 다 동시에 사용할 수는 있어도 둘 다 동시에 생략할 수는 없습니다.
- 클래스멤버목록으로는 자료와 함수를 사용합니다. 그외 구조체, 공용체, 다른 클래스, 프렌드 함수 등도 사용 가능합니다. 또한 멤버가 없는 빈 클래스를 만들 수도 있습니다. 보통 자료는 사적영역에 선언하고 함수는 공개영역에 선언하는 것이 관례입니다.
- 클래스의 멤버를 선언할 때는 같은 클래스 안에서 동일한 이름을 가진 멤버가 없어야 합니다. 단 중복될 수도 있는데 이 경우에는 매개인자의 목록이 각각 달라야 합니다. 또한 선언과 동시에 초기화를 해서는 안됩니다.

클래스를 이용한 예제를 만들어봅시다.

이상의 내용만으로는 개념이 전혀 안잡힐테니 실제로 클래스를 선언하고 이를 활용하는 예제를 만들어보도록 하겠습니다. 다음의 내용으로 test029.cpp를 만들어보기 바랍니다.

// test029.cpp
// 클래스의 선언과 사용법

#include
#include

class totprice{ //class 키워드로 totprice라는 클래스 선언
private: //사적영역을 선언
int price; //사적영역에 정수형 변수 price 선언. 초기화는 안함
public: //공개영역 선언
totprice() {price=5000;} //totprice() 함수를 만들었음
int priceis() {return price;} //priceis() 함수를 만들었음
}; //totprice 클래스의 선언 끝.

void main(void) //main() 함수의 시작
{
totprice WON; //totprice에 의한 객체 WON을 선언
cout<<"Price is "< } //main() 함수의 끝


**그림: test029.cpp의 소스파일 내용

이 프로그램의 결과는 다음과 같습니다.

Price is 5000




**그림: test029.exe의 실행화면

소스파일을 하나씩 분석해보겠습니다.

// test029.cpp

// 클래스의 선언과 사용법


#include

#include


이 부분은 설명이 필요없으리라 생각합니다. 그동안 사용한 예제파일에서 수 없이 설명한 부분이니까요. 중요한 부분은 다음 내용입니다.

class totprice{ //class 키워드로 totprice라는 클래스 선언

private: //사적영역을 선언

int price; //사적영역에 정수형 변수 price 선언. 초기화는 안함

public: //공개영역 선언

totprice() {price=5000;} //totprice() 함수를 만들었음

int priceis() {return price;} //priceis() 함수를 만들었음

}; //totprice 클래스의 선언 끝.



class라는 키워드를 이용하여 클래스를 선언했습니다. 그리고 클래스의 이름은 totprice로 정했습니다. 따라서 totprice라는 이름의 클래스가 선언된 것입니다. {}로 클래스의 블록을 열고 닫았습니다.

private: int price; 를 통해 사적영역에 정수형 변수 price를 선언했습니다. 그리고 public: totprice() {price=5000;} 명령문으로 공개 영역에 totprice() 함수를 선언했습니다. 선언과 동시에 {price=5000;} 라는 명령을 붙여서 함수의 정의도 이루어졌습니다. 즉 totprice라는 함수는 {price=5000;} 이라는 본체를 가진 함수로 정의된 것입니다.
뒤를 이어 int priceis() {return price;} 라는 명령문을 통해 priceis() 함수도 선언되고 {return price;} 라는 명령문을 통해 정의되었습니다. {return price;}라는 명령문을 통해 priceis() 함수는 앞서 사적 영역에서 선언한 price 값을 전달해주는 기능을 합니다.

이제 main() 함수의 내용을 살펴보겠습니다.

void main(void) //main() 함수의 시작

{

totprice WON; //totprice에 의한 객체 WON을 선언

cout<<"Price is "<
} //main() 함수의 끝


첫줄의 void main(void)는 설명이 필요 없을 것이고, 세번째 줄인 'totprice WON;'와 네번재 줄이 가장 중요합니다.
'totprice WON;'은 main()함수 바깥에서 선언한 totprice라는 클래스를 사용하겠다는 명령문입니다. 즉 totprice 클래스의 구조를 가진 WON이라는 이름을 객체를 만든 것입니다.
그리고 다음 줄인 'cout<<"Price is "< 이 과정을 잘 살펴보겠습니다. WON.priceis()는 totprice.priceis()와 같습니다. totprice 클래스의 구조를 가진 객체가 WON이기 때문입니다.
priceis() 함수는 return price; 이라는 명령문만 가진 함수입니다. 즉 price라는 변수의 값을 돌려주는 기능을 가진 함수입니다. 그런데 price라는 변수는 totprice() 함수에 의해 값이 대입되었습니다. 즉 totprice() 함수의 본체인 {price=5000;} 명령문을 통해 5000이라는 값이 대입되었습니다. 따라서 priceis() 함수는 return price; = return 5000; 이라는 명령문과 같습니다.
그러므로 WON.priceis()는 totprice.priceis()이고 totprice.priceis(return price) 이며, totprice.priceis(return 5000)이므로, 결국 5000이 되는 것입니다. 그래서 cout<<"Price is "<<5000; 이 되는 것입니다.

이렇게 해서 간단하게나마 클래스의 사용법을 예제를 통해서 배웠습니다. 물론 클래스의 사용법은 이보다 훨씬 복잡합니다. 기초적인 클래스 사용법만 다루어도 두꺼운 책 한 권 분량이 넘는 자료입니다. 때문에 초보자 입문서인 이 책에서는 객체와 클래스가 무엇인지 정도만 알려주는 선에서 마치겠습니다.
좀더 자세한 클래스의 사용법은 후에 기회가 된다면 중급편을 펴내 다루도록 하겠습니다.

**요약: 클래스를 이용하여 객체를 선언하고 클래스 내부의 멤버함수를 이용하여 사적 영역에 있는 자료를 외부 함수와 주고받을 수 있습니다.


<<연습문제>>
test029.cpp의 내용을 참고하여 소스파일을 만들고 ex16.cpp로 저장합니다.
제곱이라는 클래스를 선언하고 수를 입력받는 함수와 제곱 수를 계산해 돌려주는 함수를 만들어 클래스에 포함시킨 후에 main() 함수에서 제곱 결과를 보여주도록 합니다.

<<연습문제 정답>>

// EX16.CPP -- 클래스를 이용하여 제곱 수 보여주기

#include
#include

class jegob{ //class 키워드로 jegob이라는 클래스 선언
private: //사적영역을 선언
int n; //사적영역에 정수형 변수 n 선언. 초기화는 안함
public: //공개영역 선언
jegobin() {
cout<<"INput Number: "; // 출력객체로 안내문을 화면에 출력
cin>>n; // 입력객체인 cin을 사용하여 숫자를 입력받아 n에 저장
} //jegobin() 함수를 만들었음
int jegobis() {return n*n;} //jegobis() 함수를 만들었음
}; // 클래스 선언 끝.

void main(void) //main() 함수의 시작
{
jegob NUM; //jegob에 의한 객체 NUM을 선언
cout<<"Jegob Number is "< } //main() 함수의 끝





첫줄로(go top, go first line) 문화원첫화면으로(go dal site home) 강좌차림으로(go Chair) 사이트맵으로(go sitemap)




total chairpost