11 구조적 자료형 추상화와 클래스

Download Report

Transcript 11 구조적 자료형 추상화와 클래스

11장 구조적 자료형 추상화와 클래스
창원대학교 정보통신공학과
박동규
- 이질적인 구성요소들을 갖는 자료구조인 레코드(struct) 자료형을 선
언할 수 있다.
- struct 변수의 멤버에 접근할 수 있다.
- 계층 레코드 구조를 정의할 수 있다.
- 계층 레코드 변수에 저장된 값을 접근할 수 있다.
- C++ 클래스를 선언할 수 있게 된다.
- 클래스의 선언이 주어졌을 때 클래스 객체를 선언할 수 있다.
- 클래스 멤버 함수를 호출하는 클라이언트 코드를 작성할 수 있다.
- 클래스 멤버 함수를 구현할 수 있다.
- C++ 클래스를 위한 두 개의 파일(명세 파일과 구현 파일)을 구성할 수
있다.
- C++ 클래스 생성자를 작성할 수 있다.
IVIS Lab, Changwon National University
C++ Data Types
simple
integral
enum
structured
floating
array struct union class
char short int long bool
float double long double address
pointer
IVIS Lab, Changwon National University
reference
11.2 레코드(C++ 구조체)
• 구조적인 자료형은 구성요소 항목의 모임으로 이루어진다.
• 전체 모임에 대해 하나의 단순 이름이 부여되지만, 각 구
성요소는 여전히 개별적으로 접근할 수 있다.
– 레코드(C++에서는 구조체)
• 각각의 이름에 의해서 접근가능한 고정된 수의 요소를 가진 구조적
자료형이다. 그 요소들은 혼성형(의 서로 다른 형)이 가능하다.
– 필드(C++에서는 멤버)
• 레코드의 요소
IVIS Lab, Changwon National University
•
한 명의 학생을 기술하기 위한 struct를 사용
– 학생의 성, 이름 및 전체 평점 평균, 프로그래밍 과제 등급, 퀴즈의 등급, 기말 고사
등급, 최종 등급 등을 저장해야 한다.
enum GradeType {A, B, C, D, F };
struct StudentRec
{
string firstName;
string lastName;
float gpa;
// 평점 평균
int programGrade; // 0~400으로 가정
int quizGrade;
// 0~300으로 가정
int finalExam;
// 0~300으로 가정
GradeType courseGrade;
};
// 변수 선언
StudentRec firstStudent;
StudentRec student;
int
grade;
IVIS Lab, Changwon National University
struct
AnimalType
enum HealthType { Poor, Fair, Good, Excellent } ;
struct AnimalType
{
long
id ;
string
name ;
string
genus ;
string
species ;
string
country ;
int
age ;
float
weight ;
HealthType health ;
};
AnimalType
AnimalType
// declares a struct data type
// does not allocate memory
struct members
thisAnimal ;
// declare variables of AnimalType
anotherAnimal ;
IVIS Lab, Changwon National University
thisAnimal
5000
.id
2037581
.name
“giant panda”
.genus
“Ailuropoda”
.species
“melanoluka”
.country
“China”
.age
18
.weight
234.6
.health
Good
IVIS Lab, Changwon National University
anotherAnimal
6000
.id
5281003
.name
“llama”
.genus
“Lama”
.species
“peruana”
.country
“Peru”
.age
7
.weight
278.5
.health
Excellent
IVIS Lab, Changwon National University
struct type 선언
SYNTAX
struct TypeName
{
MemberList
};
MemberList
// does not allocate memory
SYNTAX
DataType MemberName ;
DataType MemberName ;
.
.
.
IVIS Lab, Changwon National University
구조체 변수에 접근
•
구조체 변수의 개별 멤버에 접근하기 위해 여러분들은 변
수의 이름과 점(dot)에 이어서 그 멤버의 이름을 주어야
한다.
– 이와 같은 표기법을 멤버 선택자(member selector)라 함
– 예)
cin >> student.finalExam;
grade = student.finalExam + student.programGrade +
student.quizGrade;
if (grade >= 900)
student.courseGrade = A;
else if (grade >= 800)
student.courseGrade = B;
else
...
IVIS Lab, Changwon National University
구조체의 군집연산
• 구조체 변수에 허용된 군집 연산들.
–
–
–
–
–
–
–
군집 연산
구조체의 허용 여부
I/O
아니오
배정
예
산술
아니오
비교
아니오
인자 전달
예, 값 또는 참조(reference)로 전달
함수의 값 반환 예
IVIS Lab, Changwon National University
• 하나의 구조체 변수는 다른 것에 배정될 수 있다.
• 두 변수가 같은 자료형으로 선언되어 있어야 한다.
StudentRec student;
StudentRec anotherStudent;
•
아래 문장은 구조체 변수 student의 전체 내용을 멤
버 대 멤버 형식으로 변수 anotherStudent에 복사한다.
anotherStudent = student;
• 반면, 군집 I/O 또한 허락하지 않는다(주된 이유는 이렇게
하는 것이 합당하지 않기 때문이다).
– 구조체 변수를 멤버 단위로 하나씩 입력과 출력을 해야 한다.
cin >> student.firstName;
cin >> student.lastName;
...
IVIS Lab, Changwon National University
계층적 레코드
• 레코드의 구성요소는 다른 레코드일 수도 있다.
• 이와 같이 구성요소들 자체가 레코드들인 레코드를 맞는
레코드를 계층적 레코드라 한다.
IVIS Lab, Changwon National University
Struct Date
{
int month;
// 1~12라 가정
int day;
// 1~31이라 가정
int year;
// 1900~2050이라 가정
};
struct Statistics
{
float
failRate;
Date lastServiced;
Int
downDays;
};
IVIS Lab, Changwon National University
struct MachineRec
{
int
idNumber;
string
description;
Statistics
history;
Date
purchaseDate;
float
cost;
};
MachineRec machine;
IVIS Lab, Changwon National University
machine 변수의 구조체
7000
5719 “DRILLING…”
.02
1
25 1999
4
3
21 1995 8000.0
.month .day .year
.failrate
.lastServiced
.idNumber .description . history
.downdays .month .day .year
.purchaseDate
machine.history.lastServiced.year has value 1999
IVIS Lab, Changwon National University
.cost
• 구성요소 접근 수식
• machine.purchaseDate
– DateType 구조체 변수
• machine.purchaseDate.month
– DateType 구조체 변수의 month 멤버
• machine.purchaseDate.year
– DateType 구조체 변수의 year 멤버
• machine.history.lastServiced.year
– statisticsType 구조체에 포함된 DateType 구조체 변수의 year 멤
버
IVIS Lab, Changwon National University
11.5 추상 자료형
• 소프트웨어가 갈수록 복잡해짐에 따라, 알고리즘과 자료
구조를 병행해서 설계해야 한다.
• 이러한 설계는 최상위 단계에서 고려되는 논리적 또는 추
상적 자료 구조에서부터, 정제과정(refinement process)
을 거쳐 C++에서 구체적인 코딩을 할 때까지 진행된다.
• 가게 물품 목록에서 기계 레코드의 논리적인 구조를 표현
하는 두 가지 방법을 살펴보았다.
– 첫 번째 방법은 동시에 모든 구성요소를 정의하는 레코드를 사용
하는 것이다.
– 두 번째 방법은 낮은 단계의 레코드를 이용해 기계의 이력을 기술
하는 일자 및 통계 정보를 정의하고, 이들 레코드를 구성요소로 갖
는 계층적 레코드임
IVIS Lab, Changwon National University
추상 자료
• 소프트웨어 설계의 세계에서는 추상화가 매우 크고도 복
잡한 소프트웨어 프로젝트를 관리하는데 필수 조건
– 컴퓨터 과학의 기초 교과 과정에서 다루는 프로그램은 대부분 작
고(50~200라인), 한 사람에 의해 전체 프로그램이 이해될 정도
– 대규모 상용 소프트웨어 제품은 몇 십만에서 심지어 몇 백만 라인
으로 구성된다.
– 소프트웨어는 다양한 형태의 추상화 사용 없이는 설계될 수 없다.
– 제어 추상화
• 행위(action)의 논리적인 속성을 그 구현으로부터 분리하는 것이다.
우리는 복잡한 알고리즘을 함수 호출에 의해 수행될 추상적인 행위로
감소시키는 함수를 작성할 때마다 제어 추상화를 하고 있는 것이다.
4.6 + sqrt(x)
IVIS Lab, Changwon National University
– sqrt 함수를 호출함으로써 제곱근 계산에 관련된 복잡한 세부사항
이 없어도 되기 때문에 우리 프로그램은 좀더 간단해진다.
– 자료 추상화
• 추상화 기법은 또한 자료에도 적용할 수 있다.
• 자료형은 값의 집합(도메인)과 그 값들에 적용 가능한 연산들의 집합
으로 구성
• 자료 추상화는 자료형의 논리적인 속성을 상세한 구현 내역으로부터
분리시키는 것
• 자료 추상화는 프로그래밍 언어 자체에서 제공하지 않는 자료형이 요
구될 때 그 역할을 수행한다.
• 그 새로운 자료형을 추상 자료형(ADT; Abstract Data Type)으로서
정의할 수 있다.
• 이 추상 자료형에 대하여 우리는 단지 그 논리적인 속성에만 관심을
갖고 상세한 구현 내역에 대한 사항은 따로 생각해도 된다.
IVIS Lab, Changwon National University
• ADT에 대한 명세 내역
TYPE
Time
DOMAIN
각 Time 값은 하루 중의 시각으로 시, 분, 초의 형식이다.
OPERATIONS
시각 설정
시각 인쇄
시각의 1초 증가시키기
두 개 시각의 동등 비교
한 시각이 다른 시각에 비해 빠른지를 검사
– ADT의 명세에서는 추상 자료값과 사용자를 위한 추상 연산을 정의한다.
– 궁극적으로 ADT는 프로그램 코드에서 구현
IVIS Lab, Changwon National University
C++ 클래스
• 클래스는 추상 자료형을 표현하기 위해 특별히 제공하는
구조적 자료형
– 클래스는 구조체와 비슷하지만 거의 항상 그것의 구성요소(클래
스 멤버)가 자료뿐만 아니라 그 자료를 조작할 수 있는 함수까지
포함하도록 설계되었다
IVIS Lab, Changwon National University
Time 클래스
// SPECIFICATION FILE
( timetype.h )
class TimeType
{
// declares a class data type
// does not allocate memory
public :
// 5 public function members
void
void
void
bool
bool
Set ( int hours , int mins , int secs ) ;
Increment ( ) ;
Write ( ) const ;
Equal ( TimeType otherTime ) const ;
LessThan ( TimeType otherTime ) const ;
// 3 private data members
private :
int
int
int
hrs ;
mins ;
secs ;
};
IVIS Lab, Changwon National University
class 형을 위하여 두개의 분리된 파일 사용
// SPECIFICATION FILE
( timetype .h )
// Specifies the data and function members.
class TimeType
{
public:
. . .
private:
. . .
};
// IMPLEMENTATION FILE
( timetype.cpp )
// Implements the TimeType member functions.
. . .
IVIS Lab, Changwon National University
Implementation File for TimeType
// IMPLEMENTATION FILE
( timetype.cpp )
// Implements the TimeType member functions.
#include “ timetype.h” // also must appear in client code
#include <iostream>
. . .
bool TimeType :: Equal ( /* in */ TimeType otherTime ) const
// Postcondition:
//
Function value == true, if this time equals otherTime
//
== false , otherwise
{
return ( (hrs == otherTime.hrs) && (mins == otherTime.mins)
&& (secs == otherTime.secs) ) ;
}
. . .
IVIS Lab, Changwon National University
클래스, 클래스 객체, 클래스 멤버
• 클래스는 자료형이며, 자료 객체가 아님
– 여느 자료형과 같이 클래스는 그 타입의 많은 객체를 생성하기 위
한 유형(패턴)이다.
– 자료형을 쿠키 제조기로, 그리고 그 자료형의 객체는 쿠키라고 생
각하라.
• 다음 선언은 Time 클래스 형의 두 객체 time1, time2를 생
성한다. 각 객체는 클래스의 비공개 자료 멤버인 hrs,
mins, secs를 위한 사본을 갖는다.
– 프로그램 실행 중 어느 한순간에, time1의 hrs, mins, secs를 위
한 사본은 값 5, 30, 10이란 값을 가질 수 있고, time2의 사본은
값 17, 58, 2를 각각 보유할 수 있다
– TimeType time1;
– TimeType time2;
IVIS Lab, Changwon National University
TimeType Class Instance Diagrams
currentTime
Set
Set
Increment
endTime
Private data:
hrs
17
mins
58
Write
Increment
Private data:
hrs
18
mins
30
secs
0
Write
LessThan
LessThan
secs
2
Equal
IVIS Lab, Changwon National University
Equal
클래스 객체의 기본 연산
• C++는 구조체와 클래스를 기본 자료형과는 다르게 취급
– 대부분의 기본 연산이 구조체와 클래스에 적용되지 않는다. 여러
분은 TimeType의 두 객체를 더하기 위해 + 연산자를 사용할 수
없으며, 동등 비교를 위해 == 연산자 또한 사용할 수 없다.
• 구조체와 클래스 객체에 유효한 두 가지 기본 연산자는 멤
버 선택(.)과 배정(=) 연산자
– 구조체처럼 점 표기법을 사용하여 클래스의 개별적인 멤버를 선택
할 수 있다.
– 클래스 객체의 이름을 쓰고 점을 찍은 뒤 멤버 이름을 부여하면 된
다.
– 다음 문장은 time1 객체의 Increment 함수를 호출한다.
time1.Increment();
IVIS Lab, Changwon National University
예제
Time time1;
Time time2;
int inputHrs;
int inputMins;
int inputSecs;
time1.Set(5, 20, 0);
// time1이 5:20:0으로 설정됨
cout << "Enter hours, minutes, seconds: ";
cin >> inputHrs >> inputMins > inputSecs;
time2.Set"(inputHrs, inputMins, inputSecs);
if (time1.LessThan(time2))
DoSomething();
time2 = time1;
time2.Write();
// 5:20:0이 출력됨
IVIS Lab, Changwon National University
// 멤버 대 멤버 배정
클래스 통용범위
• 클래스 범위는 구조체, 공용체, 클래스 내에서 멤버 이름
에 적용된다.
– 멤버 이름이 클래스 범위를 가진다는 말은 멤버 이름이 그 클래스
(또는 구조체 또는 공용체) 내로 한정된다는 것이다.
– 만약 같은 식별자(이름)가 그 클래스 외부에 선언되었다면 두 개
의 식별자는 연관성이 없다.
– Time 클래스는 Write라는 이름의 멤버 함수를 가진다.
– 같은 프로그램 내의 다른 클래스(가령, SomeClass) 또한 Write라
는 이름의 멤버 함수를 가질 수 있다.
– 그 프로그램은 어느 클래스와도 연관성이 없는 전역 함수 Write를
또한 가질 수 있다
IVIS Lab, Changwon National University
클래스 통용범위
TimeType checkInTime;
SomeClass someObject;
int n;
...
checkInTime.Write();
someObject.Write();
Write(n);
• 프로그램에서 C++ 컴파일러가 세 개의 Write 함수를 구별하는 것에
는 전혀 문제가 없다.
– 첫 두 개의 함수 호출 구문에서 점 표기법은 클래스의 멤버 선택을 의미
한다.
– 첫 문장은 Time 클래스의 Write 함수를 호출
– 두 번째 문장은 SomeClass의 Write 함수를 호출
– 마지막 문장은 점 표기법을 사용하지 않았다.
• 이 때 컴파일러는 전역 함수 Write를 호출하는 것으로 인식한다.
IVIS Lab, Changwon National University
구현파일의 범위
• in the implementation file, the scope resolution
operator is used in the heading before the function
member’s name to specify its class
void TimeType :: Write ( ) const
{
. . .
}
IVIS Lab, Changwon National University
Use of const with Member Functions
• when a member function does not modify the private
data members, use const in both the function
prototype (in specification file) and the heading of
the function definition (in implementation file)
IVIS Lab, Changwon National University
Example Using const with
a Member Function
void TimeType :: Write ( ) const
// Postcondition: Time has been output in form HH:MM:SS
{
if ( hrs < 10 )
cout << ‘0’ ;
cout << hrs << ‘:’ ;
if ( mins < 10 )
cout << ‘0’ ;
cout << mins << ‘:’ ;
if ( secs < 10 )
cout << ‘0’ ;
cout << secs ;
}
IVIS Lab, Changwon National University
파일의 분할 컴파일과 링킹
specification file
timetype.h
main program
client.cpp
implementation file
timetype.cpp
#include “timetype.h”
Compiler
Compiler
client.obj
timetype.obj
Linker
client.exe
IVIS Lab, Changwon National University
헤더 파일에서 다중 삽입의 방지
• often several program files use the same header file
containing typedef statements, constants, or class type
declarations--but, it is a compile-time error to define
the same identifier twice
• this preprocessor directive syntax is used to avoid the
compilation error that would otherwise occur from
multiple uses of #include for the same header file
#ifndef Preprocessor_Identifier
#define Preprocessor_Identifier
.
.
.
#endif
IVIS Lab, Changwon National University
전처리 지지사 #ifndef 사용 예
// timetype .h
// SPECIFICATION FILE
#ifndef TIME_H
#define TIME_H
class TimeType
{
public:
FOR COMPILATION THE CLASS DECLARATION IN
FILE timetype.h WILL BE INCLUDED ONLY ONCE
// timetype .cpp
// IMPLEMENTATION FILE
#include “timetype.h”
. . .
. . .
// client.cpp
// Appointment program
#include “timetype.h”
int main ( void )
{
private:
. . .
};
#endif
IVIS Lab, Changwon National University
. . .
}
11.8 클래스 생성자
• Time 클래스는 이미 살펴본 바와 같이 하나의 단점을 갖고 있다.
– 그것은 클라이언트 코드에서 다른 멤버 함수를 호출하기 전에 Set 함수를
호출해야 한다는 점
// 전조건:
// Set 함수가 적어도 한 번 호출되었어야 한다.
– 만약 클라이언트가 Set 함수를 먼저 호출하지 않았다면 이 전조건은 거짓
이며, 클라이언트와 함수 구현간의 협약이 깨진다.
• 클래스들은 거의 항상 자료를 캡슐화하기 때문에, 클래스를 작성하는
사람은 자료를 초기화하는 것을 사용자에게 의존해서는 안된다.
–
만약 사용자가 초기화 작업을 잊고 하지 않을 경우, 원치 않는 결과가 발
생할 것이다.
– C++는 클래스 객체의 초기화를 보장하는 클래스 생성자라 불리는 메커
니즘을 제공
• 생성자는 클래스 객체가 생성될 때마다 묵시적으로 호출되는 멤버 함수
IVIS Lab, Changwon National University
TimeType 클래스 생성자 사양
class TimeType
// timetype.h
{
public :
// 7 function members
void
Set ( int hours , int minutes , int seconds ) ;
void
Increment ( ) ;
void
Write ( ) const ;
bool
Equal ( TimeType otherTime ) const ;
bool
LessThan ( TimeType otherTime ) const ;
TimeType ( int initHrs , int initMins , int initSecs ) ; // constructor
TimeType ( ) ;
private :
int
int
int
};
// default constructor
// 3 data members
hrs ;
mins ;
secs ;
IVIS Lab, Changwon National University
TimeType 디폴트 생성자 구현
TimeType :: TimeType ( )
// Default Constructor
// Postcondition:
//
hrs == 0 && mins == 0 && secs == 0
{
hrs = 0 ;
mins = 0 ;
secs = 0 ;
}
IVIS Lab, Changwon National University
또다른 TimeType 생성자 구현
TimeType :: TimeType ( /* in */ int initHrs,
/* in */ int initMins,
/* in */ int initSecs )
// Constructor
// Precondition: 0 <= initHrs <= 23 && 0 <= initMins <= 59
//
0 <= initSecs <= 59
// Postcondition:
//
hrs == initHrs && mins == initMins && secs == initSecs
{
hrs = initHrs ;
mins = initMins ;
secs = initSecs ;
}
IVIS Lab, Changwon National University
생성자의 자동 호출
TimeType departureTime ;
// default constructor invoked
TimeType movieTime (19, 30, 0 ) ;
// parameterized constructor
departureTime
Set
Increment
Set
Private data:
hrs
0
Write
mins
0
secs
0
LessThan
Equal
movieTime
IVIS Lab, Changwon National University
Increment
Private data:
hrs
19
mins
30
Write
LessThan
secs
Equal
0
과제
• 프로그래밍 워밍업 연습문제
– 1번, 3번, 4번
– 7번
• 12시간 체계로 시간을 출력하는 프로그램을 실행하여 결과를 함께 제
출할 것
• 프로그래밍 문제
– 1번
IVIS Lab, Changwon National University
끝