Transcript C++통합

C++ Programming Language
Contents
Chapter
Chapter
Chapter
Chapter
Chapter
Chapter
Chapter
Chapter
Chapter
Chapter
01
02
03
04
05
06
07
08
09
10
C++시작하기
C++기본문법
객체지향 개념(Object-Oriented Concepts)
클래스(Class)
상속(Inheritance)
연산자 오버로딩(Operator Overloading)
템플리트(Template)
예외처리(Exception Handling)
스트림(Stream)
이름공간(Namespace)
[1]
비트교육센터
Chapter
01
C++시작하기
C++언어의 소개
C++언어란?
–
–
–
–
가장 대중적 언어인 C와 객체지향 패러다임의 만남
C언어의 특성인 저수준의 하드웨어 접근과 OOP특성인 고수준의 추상화 제공
C언어의 절차적 프로그래밍 기법과 객체 지향 프로그래밍 기법, 그리고 템플릿을 이용한 일반화
프로그래밍 기법 모두 사용 가능
순수한 의미에서의 객체지향 언어는 아니지만 가장 대중적으로 성공한 객체지향 언어
C++ 언어
절차적 언어
[3]
객체지향 언어
비트교육센터
프로그래밍 과정
1. 프로그램 목적 정의
2. 프로그램 설계
3. 소스 코드 작성
4. 컴파일 & 링크
5. 프로그램 실행
6. 프로그램 검사와 디버그
7. 프로그램 유지와 보수
[4]
비트교육센터
첫 만남, Hello, World~!
/* Hello.cpp */
#include <iostream.h>
int main(void)
{
cout << “Hello, World~!” << endl;
return 0;
}
[5]
비트교육센터
Chapter
02
C++기본문법
Contents
- 데이터 타입(Data Types)
- 연산자(Operators)
- 프로그램 제어문(Control Flow)
- 함수(Function)
- 프로젝트 구성(Project Configuration)
[7]
비트교육센터
데이터 타입(Data Type)
구분
타입
기본형
Bool형
참과 거짓의 두가지 값을 갖는 데이터 타입
정수형
소수점 이하를 가지지 못하는 숫자 타입
실수형
소수점 이하를 가지는 숫자 타입
문자형
문자 하나를 표현하는 데이터 타입
void형
타입이 정해지지 않은 자료형
열거형
변수가 가질 수 있는 가능한 값의 목록을 나타내는 타입
유도형
설명
배열
같은 타입을 갖는 변수들의 집합
구조체
다른 타입을 갖는 변수들의 집합
공용체
다른 타입의 데이터를 하나의 메모리 공간으로 관리하는 타입
포인터
대상체의 주소를 가리키는 타입
함수형
함수의 주소를 가리키는 타입
[8]
비트교육센터
bool형
특징
– 참, 거짓 중 어느 한 가지 값만 가질 수 있다.
– 정수값으로 변환될 수 있다.(true = 1, false = 0)
– 1 이상의 값은 항상 true가 된다.
bool b = 7;
// b is true.
int i = true;
// i is 1.
[9]
비트교육센터
정수형
특징
– 각 정수 타입은 세가지 형태를 띤다 : int, unsigned int, signed int
– 각 정수 타입은 세가지 크기를 지닌다 : short, int, long int
– 정수 리터럴은 네 가지 값의 형태를 지닐 수 있다
: decimal, octal, hexadecimal, character
int num;
int a, b, c;
//한 문장에서 3개의 변수 선언
int age = 30;
//선언과 동시에 초기화
[10]
비트교육센터
실수형
특징
– 소수점 이하를 가지는 실수를 표현하고 저장하는 데이터 타입
– 실수형 데이터 타입은 세가지 크기를 가진다 : float, double, long double
(기본 타입 : double)
float a = 10, b = 20;
double percent = a/100;
double c = 0.3;
[11]
비트교육센터
문자형
특징
–
–
–
–
하나의 문자 혹은 하나의 기호를 표현하고 저장하는 데이터 타입
표준 ASCII 코드(0 ~ 127) 사용(정수값 표현 가능)
문자의 표현시 반드시 작은 따옴표(‘ ’)로 묶어준다
출력되지 않는 문자(Escape Sequences)를 사용한다
char grade;
char gradeA = ‘A’, gradeB = 66;
//선언과 동시에 초기화
[12]
비트교육센터
void형
특징
– 타입이 정해지지 않은 데이터를 위한 자료형
– 객체를 정의하기 위해 사용될 수 없다.
– 함수의 리턴 값 혹은 인자가 없다는 의미로 사용될 수 있다.
void x;
// 오류 발생 : there are no void objects.
void f (void); //함수 f는 인자와 리턴 값을 갖지 않는다.
[13]
비트교육센터
데이터 타입의 크기
특징
– 데이터 타입의 크기는 시스템이나 운영체제, 컴파일러마다 달라질 수 있다.
: <limits.h> 참조
– 타입간의 크기 순서는 정해져 있다.
1  sizeof(char)  sizeof(short)  sizeof(int)  sizeof(long)
sizeof(float)  sizeof(double)  sizeof(long double)
– sizeof 연산자를 이용하여 자료형의 크기를 확인할 수 있다.
[14]
비트교육센터
[15]
비트교육센터
Enum(1)
특징1
–
–
–
–
사용자가 정수형 값에 이름을 주어 의미를 표현하고자 할 때 사용
정의된 후에는 정수형 타입으로 사용됨
값을 정하지 않는 경우, 디폴트로 0부터 증가하는 값을 가짐
프로그램의 가독성을 향상시키기 위해 사용
enum colors {RED, YELLOW, BLUE, GREEN};
//RED=0,YELLOW=1,BLUE=2,GREEN=3
enum font {ARIAL, CENTURY=10, GOTHIC, TIMESROMAN=20};
// ARIAL=0,CENTURY=10,GOTHIC =11,TIMESROMAN=20
[16]
비트교육센터
Enum(2)
특징2
– 값의 범위는 0부터 가장 가까운 2진 자릿수의 최대값까지이다.
– 정수형 값을 명시적으로 형변환하여 대입할 수 있다.
enum e1 {open, close};
//range : 0 ~ 1
enum e2 {a = 3, b = 10}
//range : 0 ~ 15
enum flag {a = 1, b = 2, c = 4, d = 8};
flag f1 = 5;
//type error
flag f2 = flag(5);
//OK
//range : 0 ~ 15
flag f3 = flag(c|d); //OK
[17]
비트교육센터
typedef
특징
– 어떤 타입에 대한 새로운 이름을 부여하는 것
– 새로운 타입이 생성되는 것이 아니라 별명이 생긴다고 할 수 있음
typedef char* PCHAR;
typedef unsigned long ulong;
PCHAR p1;
ulong var1;
[18]
비트교육센터
구조체(1)
특징1
–
–
–
–
임의 타입의 변수들의 집합체
구성하는 모든 멤버 변수들의 데이터 타입이 같아도 되고, 달라도 된다.
포인터 변수나 배열도 멤버 변수로 사용할 수 있다.
멤버 변수의 접근을 위해서 dot(.)을 사용한다.
struct phone {
//phone 이라는 이름(태그)의 구조체 선언
char name[20];
//첫번째 구조체 멤버
char phoneno[20];
//두번째 구조체 멤버
}
struct phone myphone;
cout << myphone.name << endl;
cout << myphone.phoneno << endl;
[19]
비트교육센터
구조체(2)
특징
– struct로 정의된 타입은 typedef를 이용하여 독립적인 타입으로서 사용될 수 있다.
– 동일한 타입일 경우, 대입과 복사 연산이 가능하다.
typedef struct {
char name[20];
//첫번째 구조체 멤버
char phoneno[20];
//두번째 구조체 멤버
} Phone;
Phone myphone;
strcpy(myphone.name, “Hong, Gil-Dong”);
strcpy(myphone.phoneno, “02-111-1234”);
Phone yourphone = myphone;
[20]
비트교육센터
구조체(3)
특징
– 변수를 정의할 때 초기화 블록을 사용하여 초기화할 수 있다.
– 중첩 구조체를 선언할 수 있다.
(중첩 구조체 : 다른 struct 타입의 변수를 포함하는 구조체)
– 중첩 초기화를 통해 모두 한꺼번에 초기화할 수 있다.
typedef struct {
char name[20];
//첫번째 구조체 멤버
char phoneno[20];
//두번째 구조체 멤버
} Phone;
Phone myphone = {“Hong, Gil-Dong”, “02-111-1234”};
[21]
비트교육센터
구조체(4)
특징
– Strict Type Checking : 두 구조체 타입이 같은 타입의 동일한 이름을 가진 변수들
을 똑같이 가지고 있더라도, 구조체 이름이 다르다면, 다른 타입으로 인식한다.
struct phone{
char name[20];
char phoneno[20];
};
struct person {
char name[20];
char phoneno[20];
};
struct phone ph = {“Hong, Gil-Dong”, “02-111-1234”};
person pe = ph; //type mismatch error
[22]
비트교육센터
구조체(5)
특징
–
–
–
–
비트 단위로 타입 내의 변수들을 구성할 수 있다.
메모리의 효율성을 제공한다.
구조체 선언에서 각 비트 필드에 레이블을 붙이고 크기를 지정한다.
각 비트마다 가질 수 있는 값은 0과 1 뿐이다.
struct sreg {
unsigned int enable : 1;
unsigned int page : 3;
unsigned int : 1; //unused
unsigned int mode : 2;
unsigned int access : 1;
unsigned int length : 1;
};
struct sreg s1;
s1.page = 5;
[23]
비트교육센터
공용체(Union)
특징
– struct와 유사하나, 타입 내의 모든 멤버 변수들 중 가장 큰 크기를 가진 변수만큼만
메모리가 할당된다.
– 타입내의 여러 멤버 변수들 중 한가지로만 사용될 수 있다.
union MyType
{
int num1;
double num2;
char ch;
};
//이 때, mytype 타입의 변수들은 8bytes(=>double의 크기)의 저장공간을
사용하게 된다.
[24]
비트교육센터
포인터(1)
특징
– 메모리의 주소값을 저장하는 변수
– 타입T*의 변수는 T타입 객체의 주소를 가질 수 있다.
– 배열이나 함수를 가리키는 포인터를 정의할 수 있다.
– 간접연산자(*)
: 뒤에 포인터 이름이나 주소가 따라올 경우, *는 가리켜진 주소의 메모리 공간에 저
장된 값을 반환한다.
– 주소연산자(&)
: 뒤에 변수 이름이 따라올 경우, 그 변수가 위치한 메모리 공간의 주소를 반환한다.
int num1 = 20;
0x1000
num1 = 20
int num2 = 30;
0x1004
num2 = 30
0x1008
pi = 0x1000
int *pi;
pi = &num1;
cout << *pi << endl;
0x100c
[25]
비트교육센터
포인터(2)
int * pi;
//pointer to int
char ** ppc;
//pointer to pointer to char
int (*ap)[4];
//pointer to array of 4 ints
int (*fp) (char*);
//pointer to function taking a char* arguments;
//returns an int
int * f(char *);
//function taking a char* argument;
//returns a pointer to int*
pi
ppc
ap
function code for
int f(char)
123
‘a’
123
234
456
678
[26]
비트교육센터
포인터(3)-void*
특징
–
–
–
–
–
선언시에 포인터의 타입이 정해지지 않는다.
모든 객체의 포인터 변수는 void* 타입으로 매핑될 수 있다.
void* 타입의 객체는 다른 타입으로 명시적인 변환이 가능하다.
void* 타입의 두 객체에 대한 동일성 비교가 가능하다.
그 외의 연산은 불가능하다.
void f(int * pi)
{
void* pv = pi;
//ok : implicit conversion
*pv;
//error : can’t dereference void*
pv++;
//error : can’t dereference void*
int* pi2 = (int*) pv;
//ok : explicit conversion
double* pdl = pv;
//error
}
[27]
비트교육센터
배열(1)
특징
–
–
–
–
한가지 데이터 타입으로 이루어진 일련의 요소의 모임
배열은 생성과 동시에 초기화할 수 있다.
콤마로 구분된 값의 목록을 중괄호로 둘러싸는 방법으로 초기화한다
초기화 값의 목록이 배열의 크기보다 모자랄 경우 컴파일러는 나머지 요소의 값을 0
으로 설정한다.
– 초기화 값의 목록이 배열의 크기보다 클 경우 컴파일러는 오류로 처리한다.
int v1[4] = { 1, 2, 3, 4 };
int v2[] = { 5, 6, 7 };
int v3[3] = { 1 };
int v4[4] = { 2, 3, 4, 5, 6, 7 }; //error
v1
1
2
3
v2
5
6
7
v3
1
0
0
4
[28]
비트교육센터
배열(2)
특징
– 다차원 배열을 구성할 수 있으며, 초기화 또한 가능하다.
– 2차원 배열
: 배열의 배열(행과 열로 구성되는 표 형태)
– 3차원 이상의 배열
: 행과 열로 쌓여 있는 표가 여러개 쌓여 있는 형태
int v1[2][3] = { {1,2,3}, {4,5,6} };
int v2[][3] = { {1,2,3}, {4,5,6}, {7,8,9} };
v1
v1
1
2
3
4
5
6
1
2
3
=> 논리적 구조
4
5
[29]
6
=> 물리적 구조
비트교육센터
Reference(1)
특징
– 이미 존재하는 객체에 붙이는 별명
– 항상 초기화되어야만 사용 가능하다.
– 레퍼런스로 수행하는 연산은 레퍼런스가 참조하는 변수를 가지고 수행하는 연산과
같은 효과를 나타낸다.
void f()
{
int num
1 = 10;
int &ref = num1;
int num2 = ref;
ref = 20;
}
[30]
비트교육센터
[31]
비트교육센터
Reference(2)
특징
– 레퍼런스는 인자 전달(argument passing)에서 call-by-reference를 구현한다.
void increment(int& aa) {aa++;}
void g()
{
int x = 1;
increment(x);
}
[32]
비트교육센터
Constant(1)
특징
– 상수는 선언된 값을 변경할 수 없으며, 항상 초기화하여 사용해야 한다.
const int model = 90;
const int v[] = {1, 2, 3, 4};
const int x;
//error : no initialization
void f()
{
model = 200;
//error
v[2]++;
//error
}
[33]
비트교육센터
Constant(2)
특징
– 값과 포인터를 상수화할 수 있다.
void f(char* p)
{
char s[] = “Gorm”;
const char* pc = s; //constant
pc[3] = ‘g’;
//error
pc = p;
//OK
}
[34]
비트교육센터
[35]
비트교육센터
Storage Class(1)
유효범위(Scope)
– 어떤 변수에 접근할 수 있는 구역 혹은 프로그램의 구역
– 블록 범위 : 서로 짝이 되는 { 와 } 사이의 영역 내에서 유효한 범위
– 파일 범위 : 변수가 정의된 지점으로부터 그 파일의 끝까지 유효한 범위
연결성
– 외부 연결성 : 여러 파일로 구성된 프로그램의 어디서든 사용할 수 있는 것
– 내부 연결성 : 그 변수가 선언된 파일 안에서만 사용할 수 있는 것
– 연결성 없음 : 자신이 정의된 블록 내에서만 사용할 수 있는 것
저장기간
– 정적 저장 기간 : 변수가 프로그램이 실행되는 기간 내내 존재하는 것
– 자동 저장 기간 : 변수가 정의된 블록에 프로그램 제어권이 들어왔을 때부터 블록을
빠져나갈 때 까지 존재하는 것
[36]
비트교육센터
Storage Class(2)
자동 변수
– 보통 특정 블록, 혹은 함수의 시작 부분에 선언되며, 그 블록 혹은 함수 내에서만 사
용된다.
레지스터 변수
– CPU와 같은 빠른 메모리에 저장되며, 그 성격은 자동 변수와 같다.
블록범위 정적변수(Static)
– 자동변수와 같이 특정 블록 혹은 함수 내에서만 사용될 수 있으나, 해당 블록 혹은
함수 종료 후에도 존재하게 되며 프로그램이 완전히 종료되어야 소멸된다.
void StaticFunction(int val)
{
이 함수가 처음 호출되었을 때만
초기화되고, 그 이후에 함수가
호출될 때는 이전에 계산된 값을
그냥 사용하게 된다.
static int count = 0;
count = count + val;
cout << count << endl;
}
[37]
비트교육센터
Storage Class(3)
외부 연결 정적 변수(전역변수)
– 함수의 외부에 선언하며 프로그램의 시작부터 종료까지 프로그램 전체(모든 파일)
에서 사용한다.
내부 연결 정적 변수(전역변수)
– 함수의 외부에 선언하며 프로그램의 시작부터 종료까지 살아있지만, 변수의 선언이
포함된 파일 내에서만 사용된다.
[38]
비트교육센터
데이터 타입의 변환(형 변환)
암시적 형 변환(자동 형 변환)
– 연산자를 기준으로 하여 왼쪽의 데이터와 오른쪽의 데이터의 타입이 서로 다른 경
우에 연산을 수행하기 위하여 발생하는 형 변환
– Type Promotion(형 승격)
동일 종류의 데이터 타입에 대해 타입의 표현 범위가 큰 쪽으로 타입을 변환한다.
(예) bool, char, short -> int
– Standard Type Conversion(표준 형 변환)
기본 데이터 타입간의 가능한 형 변환을 이용하여 찾는다.
(예) int <- -> double
명시적 형 변환(강제 형 변환)
– 프로그래머의 명시적인 선언에 의해서 발생하는 형 변환
(예) float f = (float)100;
[39]
비트교육센터
연산자(Operators)
연산자 종류
연산 기호
특징
범위지정연산자
::
변수에 대한 접근 범위를 지정하기 위한 연산자
산술 연산자
+, - , *, / , %
%(나머지) 연산자는 피연산자로 정수형이 온다.
증감연산자
++, --
대입연산자
=, -=, +=, …
비교 연산자
<, <=, >, >=, ==,!=
연산 결과가 참이면 1을 거짓이면 0
논리 연산자
&&, ||, !
연산 결과가 참이면 1을 거짓이면 0
비트 연산자
&, |, ~, ^
변수 자체의 논리가 아닌 각 비트별 논리 연산
쉬프트 연산
<<, >>
간접 연산자
*
피 연산자의 값이 메모리 주소일 때 유효하다.
주소 연산자
&
해당 변수가 할당된 주소를 확인
형변환 연산자
(변환할 type)
구분 연산자
. , ->
조건 연산자
조건?처리1:처리2
기타
(),[],{}
단항 연산자로 피연산자의 위치에 따라 차이가 있다.
우항의 연산결과를 좌항의 변수에 대입한다.
비트 단위의 쉬프트로 기본적으로 빈 곳은 0을 채움
명시적 형변환에 사용된다.
구조체나 공용체 처럼 변수와 멤버사이의 구분자
조건이 참이면 처리1을 거짓이면 처리2를 수행
괄호 연산자는 우선순위가 가장 높다.
[40]
비트교육센터
범위 지정 연산자(Scope Resolution)
특징
– 접근하려고 하는 변수에 대한 범위를 지정할 때 사용하는 연산자
– 전역 변수에 대한 접근을 위해 사용하기도 하므로, 전역 변수 연산자라고도 한다.
int amount = 123;
void main()
{
::amount = 100;
cout << “::amount = “ << ::amount << endl;
}
[41]
비트교육센터
산술연산자
특징
– 덧셈, 뺄셈, 곱셈, 나눗셈, 나머지 연산을 수행하는 가장 기본적이며 자주 사용하는
연산자
연산자
우선순위
의미
결합방식
()
1
+,-(단항)
2
양수, 음수
오른쪽 -> 왼쪽
*,/,%
3
곱셈, 나눗셈,나머지
왼쪽 -> 오른쪽
+,-(이항)
4
덧셈, 뺄셈
왼쪽 -> 오른쪽
왼쪽 -> 오른쪽
[42]
비트교육센터
증감연산자
특징
– 피연산자를 1씩 증가 혹은 감소 시키는 단항 연산자
– 연산자의 위치에 따라 증감의 시점이 달라지게 되어(전위/후위 연산자), 수식 내에
서 사용시에 주의해야 한다
연산자
의미
++a
값을 1 증가 후 연산 수행
a++
연산을 수행 후 값을 1 증가
--a
값을 1 감소 후 연산 수행
a--
연산을 수행 후 값을 1 감소
[43]
비트교육센터
대입연산자
특징
– 우변값을 좌변에 대입하는 연산자
연산자
의미
=
Simple assignment
*=
Multiplication assignment
/=
Division assignment
%=
Remainder assignment
+=
Addition assignment
-=
Subtraction assignment
<<=
Left-shift assignment
>>=
Right-shift assignment
&=
Bitwise-AND assignment
|=
Bitwise-OR assignment
^=
Bitwise-Exclusive-OR assignment
[44]
비트교육센터
비교연산자(관계연산자)
특징
– 좌변값과 우변값을 비교하여 누가 큰지, 작은지, 같은지, 같지 않은지 등의 관계를
알려주는 연산자
– 비교 조건이 만족되면 true(=1), 만족하지 못하면 false(=0)를 반환
연산자
<
의미
좌변값이 우변값보다 작은가?
<=
좌변값이 우변값과 같거나 작은가?
==
좌변값과 우변값이 같은가?
>=
좌변값이 우변값과 같거나 큰가?
>
좌변값이 우변값보다 큰가?
!=
좌변값과 우변값이 같지 않은가?
[45]
비트교육센터
논리연산자
특징
– 둘 이상의 비교(관계)식을 결합하는 연산자
연산자
의미
&&
논리곱 : AND
피연산자가 모두 true일 경우 true를 반환
||
논리합 : OR
피연산자 중 하나라도 true이면 true를 반환
!
부정 : NOT
피연산자가 true면 false를, 피연산자가 false면 true를 반환
[46]
비트교육센터
비트 논리 연산자
특징
– 비트 단위(0 또는 1)로 연산을 할 때 사용하는 연산자
– 정수 타입 데이터들만 사용할 수 있다 (char타입 포함)
연산자
의미
~
비트단위 부정(NOT)
1은 0으로, 0은 1로 반전시켜 반환
&
비트단위 논리곱(AND)
두개의 비트가 모두 1일때 1을 반환
|
비트단위 논리합(OR)
두개의 비트 중 하나라도 1이면 1을 반환
^
비트단위 배타적 논리합(Exclusive OR : XOR)
두개의 비트가 서로 다를 경우에 1을 반환
[47]
비트교육센터
비트 시프트 연산자
특징
– 비트를 왼쪽에서 오른쪽으로, 혹은 오른쪽에서 왼쪽으로 이동시키는 연산자
연산자
의미
<<
왼쪽 시프트 연산자
왼쪽 피연산자의 값의비트들을 오른쪽 피연산자가 나타내는 자
리 개수만큼 왼쪽으로 이동
>>
오른쪽 시프트 연산자
왼쪽 피연산자의 값의비트들을 오른쪽 피연산자가 나타내는 자
리 개수만큼 오른쪽으로 이동
[48]
비트교육센터
변환연산자(캐스트연산자)
특징
– 수식내에서 변수의 데이터 타입을 강제로 변환시키는 연산자(명시적 형변환)
int a;
double b = 10.25;
a = (int)b; //b의 실수값이 정수형으로 변환된 후 a에 대입된다.
[49]
비트교육센터
조건연산자
특징
– if~else문의 효과를 내는 연산자
– 피연산자를 3개 취하기 때문에 삼항연산자라고도 불린다
int a = 10, b;
b = (a > 0) ? 1 : 0; //a의 값이 0보다 크면 1을, 그렇지 않으면 0을 대입
a = (b == 1) ? 1 : 0; //b의 값이 1이면 1을, 그렇지 않으면 0을 대입
[50]
비트교육센터
new & delete
특징
– new : 동적으로 메모리를 할당하는 연산자
– delete : new연산자에 의하여 할당된 메모리를 해제하는 연산자
– 두 연산자 모두 힙(heap)영역의 메모리를 관리하는데 사용된다.
void* operator new(size_t);
void operator delete(void*);
void* operator new[] (size_t);
void operator delete[] (void*);
int *pi = new int;
delete pi;
[51]
비트교육센터
프로그램 제어문(Control Flow)
조건에 따른 분기와 점프
: 주어진 조건에 따라 다음에 오는 명령의 실행 여부를 결정하여 상황에 따라 다르게
동작시키는 문장
– if문
– switch문
– goto문
반복문
: 비슷한 형태의 문장들을 여러 번 반복해서 실행하는 문장
– while문
– do while문
– for문
– continue & break
[52]
비트교육센터
if문
if (condition1)
statement1;
else if (condition2)
statement2;
else
statement3;
condition1
false
true
condition2
false
true
•
condition1이
true면 statement1을
false면 condition2를 검사한다
•
condition2가
true면 statement2를
false이면 statement3을 수행한다.
statement1
[53]
statement2
statement3
비트교육센터
switch문
switch (n)
{
case value1 : statement1;
break;
case value2 : statement2;
break;
default :
statement3;
}
value1
other value
value2
statement1
•
n =?
statement2
statement3
n의 값이
value1이면 statement1을 수행한다.
value2이면 statement2을 수행한다.
other value면 statement3를 수행한다.
[54]
비트교육센터
while문
– 조건을 먼저 검사하여 true 인 동안
만 문장들을 실행하는 진입 조건형
루프
condition
false
true
while (condition)
{
statement1;
statement2;
statement3;
}
statement4;
statement1
statement2
statement3
statement4
•
condition이 true인 동안 { 과 } 사이의
블럭내의 statement1, statement2,
statement3을 반복하여 수행한다.
[55]
비트교육센터
do-while문
– 일단 루프내의 문장들을 한번 실행
한 후 조건을 검사하여 false가 될때
까지 루프내의 문장들을 반복 실행
하는 탈출 조건형 루프
statement1
statement2
do
{
statement3
statement1;
statement2;
statement3;
} while (condition)
statement4;
true
condition
false
statement4
•
statement1, statement2, statement3를 한번
실행한 후 condition을 검사하여 true인 동안
statement1,2,3을 반복해서 수행한다.
[56]
비트교육센터
for문
– 제어변수를 사용하며, 조건식 외에
초기문과 증감문을 기본적으로 포함
하여 반복 횟수가 미리 정해지게 되
는 반복문
초기문
condition
for (초기문; 조건식; 증감문)
{
statement1;
statement2;
}
statement3;
false
true
statement1
statement2
증감문
•
•
루프에 진입하기 전에 초기문을 수행하고, 조건식
의 true/false를 조사한 후 true인 경우에
statement1, statement2를 수행한다.
한번의 반복루프 수행마다 증감문을 한번씩 수행
하고 다시 조건식을 검사하여 다음 번 반복루프의
수행여부를 결정하게 된다.
[57]
statement3
비트교육센터
continue & break
continue
– 반복하고 있는 루프의 나머지 문장은 건너뛰고, 그 다음의 반복주기를 시작한다.
– switch문 내에 break문장이 있으면 switch문을 빠져나간다.
– continue문이 중첩된 반복루프 안에 있을 경우에는 가장 안쪽의 반복루프에만 영
향을 미친다.
break
– 자신을 둘러싸고 있는 반복루프를 빠져나와 루프 밖의 문장을 수행시킨다.
– break문이 중첩된 반복루프 안에 있을 경우에는 가장 안쪽의 반복루프에만 영향을
미친다.
[58]
비트교육센터
함수(Functions)
함수란
– 특정 기능을 위해 설계된 프로그램의 독립적 단위이다.
– 적당한 인자(매개변수)를 주면 그에 따른 출력(반환 값)이 존재한다.
함수를 사용하는 이유
–
–
–
–
재사용성(reusability)
분할 정복 접근법(divide-and-conquer approach)
모듈화가 이루어져, 읽기와 수정 작업이 쉬워진다.
프로그램의 세부사항보다 프로그램의 전반적인 설계에 집중할 수 있다.
함수의 종류
– 표준 함수
– 사용자 정의 함수
[59]
비트교육센터
함수의 선언과 정의
함수의 선언
– 함수의 몸체는 없이 함수의 이름과 입력 매개변수(인자), 리턴 데이터 타입으로 구
성된다.
– 함수의 호출 전에 함수의 선언이 먼저 와야 한다.
함수의 정의
– 함수의 선언과 동시에 기능에 해당하는 프로그램모듈(몸체)을 가진다.
[60]
비트교육센터
매개변수 전달방법(I)
매개변수
– 함수를 호출하는 외부에서 함수 내부로 넘겨주고 싶은 데이터가 있는 경우 매개변
수를 사용한다.
– 경우에 따라서는 매개변수가 없을 수도 있다.
매개변수 전달방법(함수의 호출 방식)
– 값에 의한 전달방식(call by value)
: 변수의 값을 복사해서 전달하는 방법(C에서의 기본방법)
함수 내부에서 외부로부터 매개변수로 전달되는 변수의 값을 직접 바꿀 수 없다.
[61]
비트교육센터
매개변수 전달방법(II)
매개변수 전달방법(함수의 호출 방식) – cont’d
– 참조에 의한 전달방식(call by reference)
: 함수 내부에서 외부로부터 매개변수로 전달되는 변수의 값을 직접 바꿀 수 있다.
변수의 메모리 주소를 전달하는 방식(포인터를 이용하여 참조 전달 방식 구현)과
레퍼런스를 이용한 전달방식이 있다.
: 리터럴, 상수, 변환을 요청하는 인자는 const &형으로 받아야 한다.
[62]
비트교육센터
반환 값(Value Return)
값의 반환 방식
– 일반적인 형 변환 규칙을 따른다.
– 리턴 타입이 참조형이나 포인터형인 경우에는 함수 종료 후에도 지속되는 객체
(static변수, 전역 변수 등)를 전달하여야 한다.
int* f()
int& f()
{
{
int local = 1;
int local = 1;
............
............
return &local; //bad
return local; //bad
}
}
[63]
비트교육센터
재귀함수(Recursive Function)
특징
– 함수 내에서 자기 자신을 호출하는 함수
– 재귀를 종료시키는 조건 검사 코드를 넣지 않으면 무한히 자신을 호출하게 된다.
long factorial(int n)
{
long res;
long factorial(int n)
{
long res;
for (res=1; n>1; n--)
res *= n;
if (n > 0)
res = n * factorial(n-1);
else
res = 1;
return res;
}
return res;
}
[64]
비트교육센터
함수 오버로딩(1)
함수 오버로딩이란?
– 동일한 이름의 함수를 중복해서 여러 개 정의하는 것
특징
– 함수의 인자 개수와 인자의 데이터 타입에 따라 서로 다른 함수로 인식한다.
void print(double);
void print(long);
void f()
{
print(1L); //call print(long)
print(1.0); //call print(double)
}
[65]
비트교육센터
함수 오버로딩(2)
실행할 함수 찾는 순서
1. Exact match : 동일한 타입을 가진 함수를 찾는다.
(e.g.) 배열이름 -> 포인터,
함수이름-> 함수에 대한 포인터,
T -> const T
2. Type promotion : 동일 종류의 타입에 대해 타입의 표현 범위가 큰 쪽으로 타입을
변환하여 찾는다.
(e.g.) bool, char, short -> int,
float->double,
double->long double
3. Standard type conversion
(e.g.) int <-> double,
derived* -> base*,
T* -> void*
int -> unsigned int
4. User-defined type conversion :사용자가 정의한 타입 형 변환 함수를 적용하여 찾
는다.
5. Find ellipsis : 생략 인자를 표현한 함수가 있는지를 찾는다.
[66]
비트교육센터
함수 오버로딩(3)
특징
– 리턴 타입은 함수 오버로딩에 영향을 주지 않는다.
– 함수 오버로딩은 함수 선택에 있어서 모호성을 유발시킬 수 있다.
void f1(char);
void f1(long);
void f2(char*);
void f2(int*);
void k(int i)
{
f1 (i);
//ambiguous: f1(char) or f1(long)
f2(0);
//ambiguous: f2(char*) or f2(int*)
}
[67]
비트교육센터
[68]
비트교육센터
기본 매개변수(Default Arguments)
특징
– 기본 값을 제공함으로써, 함수의 중복 선언을 막고, 함수 정의를 간단하게 할 수 있
다.
– 함수 선언에서 기본 값은 매개변수 순서상 맨 뒤에서부터 명시할 수 있다.
void print (int value, int base = 10);
void f()
{
print (31);
//결과 : 31
print (31, 10);
//결과 : 31
print (31, 16);
//결과 : 1f
print (31, 2);
//결과 : 11111
}
[69]
비트교육센터
매개변수가 정해지지 않은 함수
특징
– 매개변수의 수를 결정할 수 없을 경우, 생략인자(...)를 가진 함수를 정의할 수 있다.
void printf (const char* ...);
printf (“Hello World~!\n”);
printf (“Myname is %s\n“, “Hong”);
printf(“%d + %d = %d\n”, 10, 20, 10+20);
[70]
비트교육센터
함수 포인터(1)
특징
–
–
–
–
–
–
함수는 함수의 이름 뿐만 아니라 함수의 주소를 이용하여 부를 수 있다.
함수 이름이 포인터가 된다.
함수 포인터 타입은 함수의 반환하는 데이터 타입과 매개변수로 결정된다.
함수 포인터를 사용하면 실행 시에 함수를 매개변수로 입력 받을 수 있다.
typedef를 이용하여 함수 포인터 타입의 변수를 선언할 수 있다.
함수 호출 시, *(dereferencing)의 사용은 선택적이다.
void (*f1) (string) = &error;
//OK
void (*f2) (string) = error;
//OK
void g()
{
f1 (“Vasa”);
//OK
(*f1) (“Mary Rose”); //OK
}
[71]
비트교육센터
함수 포인터(2)
특징
– 동일한 형식의 함수를 필요에 따라 선택적으로 부르고자 하는 경우 매우 유용하다.
– 함수 포인터는 자신과 동일한 함수 선언을 가진 함수만을 가리킬 수 있다.
typedef void (*PF) ();
PF edit_ops[] = { &copy, &cut, &paste, &search, &replace};
PF file_ops[] = { &open, &append, &close, &write };
PF* button2 = edit_ops;
PF* button3 = file_ops;
button2[3] (); //call button’s 3rd function
[72]
비트교육센터
[73]
비트교육센터
[74]
비트교육센터
인라인 함수(Inline Function)
특징
– 인라인 함수는 그것이 사용되는 위치에 코드 형태로 포함된다.
– 함수 호출 과정이 생략되므로 성능 향상을 기대할 수 있다.
– 컴파일러에 따라서 성능 향상에 오히려 해가 된다면 무시되기도 한다.
inline int fac(int n) { return ( n < 2 ) ? 1 : n*fac(n-1);}
int main()
{
fac(100);
fac(200);
}
[75]
비트교육센터
매크로 함수(Macro)
특징
–
–
–
–
매크로는 컴파일 전단계(precompile phase)에서 코드로 치환된다.
매크로 이름은 오버로딩 될 수 없다.
재귀 형태로 정의할 수 없다.
매크로 함수는 가능한 인라인 함수로 정의하는 것이 바람직하다.
[76]
비트교육센터
프로젝트 구성(Project Configuration)
- 조건부 컴파일(Conditional compilation)
- 분할 컴파일(Separate compilation)
- 헤더파일(Header files)
[77]
비트교육센터
조건부 컴파일(1)
특징
– 소스 파일의 일부분을 선택적으로 컴파일 할 수 있도록 지원한다.
– 조건에 맞추어 특정 정보 또는 코드 블럭을 수행하거나 무시할 것을 컴파일러에게
지시한다.
– 헤더파일에 대한 중복 정의를 막는다거나 프로그램 디버깅 등의 작업 시에 효과적
으로 사용할 수 있다.
#if constant-expression
#ifdef identifier
#ifndef identifier
#elif constant-expression
#else
#endif
defined(identifier)
defined identifier
[78]
비트교육센터
조건부 컴파일(2)
#if defined(PHONE)
#if GRADE > 3
phone();
#define FLAG 1
#elif defined(FAX)
#if MAX == 1
fax();
#define MAXLEN 200
#else
#else
error();
#define MAXLEN 100
#endif
#endif
#else
#if !defined(MYEXAM_H)
#define FLAG 0
#define MYEXAM_H
#if MAX == 1
#define MAXLEN 100
#else
struct MyExam{...};
#define MAXLEN 50
#endif
#endif //!defined(MYEXAM_H)
#endif
[79]
비트교육센터
분할 컴파일
특징
– 한 파일에 모든 코드를 구성하는 것은 불가능
– 여러 파일에 분할하여 코드를 구성함으로써
• 프로그램을 이해하기 쉽게하고
• 재컴파일 시 수정된 파일만을 컴파일함으로써 시간을 절약한다.
source file
compiler
linker
separately compiled parts
[80]
비트교육센터
Header File
헤더 파일에 포함될 수 있는 것들
named namespaces
namespace SEC { /*...*/}
type definitions
struct Point {int x, y;};
template declarations
template<class T>class Z;
template definitions
template<class T> class V{/*.......*/};
function declaration
extern int strlen(const char*)
inline function definitions
inline char get() {return *p--;}
data declaration
extern int gnum;
constant definitions
const float pi = 3.141592;
enumerations
enum Color {red, blue, green};
name declarations
class Person;
Include directives
#include “phone.h”
macro definitions
#define LEVEL 4
conditional compilation directives
#ifdef_cplusplus
comments
/* this file is sample. */
[81]
비트교육센터
Chapter
03
객체지향 개념
Contents
- Preliminary : 객체지향 개념(Object-Oriented Concepts)
- 클래스(Class)
- 파생 클래스(Derived Class) : Inheritance
[83]
비트교육센터
객체지향 개념
현실 세계
현실 세계에 대한
추상적 모델링
추상화된 현실 세계
강의 상황에
대한 추상적
표현
강의 상황
[84]
비트교육센터
Key Elements of OO Concepts
Object
Method
ENCAPSULATION
Message
Attribute
INHERITANCE
Class
Instance
Class Hierarchy
POLYMORPHISM
[85]
비트교육센터
객체(Object)
실세계에 존재하는 모든 것
자체적으로 유일성을
보장할 수 있는 것
상황에 따라 동일한 존재가
객체가 될 수도 되지 않을 수도
있다
독립적으로 존재하여, 스스로
행위와 상태를 변경할 수 있는 것
[86]
비트교육센터
속성(Attribute)
객체를 내부 상태를
표현하기 위한 것
한 객체를 다른 객체와
구분해 주기 위한 값
유일성을 보장해 주기 위한
값을 식별자라 한다
대상1 : 홍길동
대상2 : 황진이
깊이 : 천년
깨질 가능성 : 없음
대상1 : 군대간 남
대상2 : 남은 여
깊이 : 몇 년
깨질 가능성 : 상당히 많음
[87]
비트교육센터
메시지(Message)
객체의 내/외부에서 객체로
전달되는 이벤트
객체간의 전달 신호
(객체가 자신에게 전달하는 신호)
객체간에 서로 노출되며, 받은
메시지를 무시할 수 있다
실세계의 동적인 상황을
기술하기 위한 수단
관계 여
Message :
복부를 향해 주먹을 날림
군대 남
Message :
머리를 향해 2단 돌려 차기를 함
[88]
새로운 남
비트교육센터
메소드(Method)(1)
메시지를 처리하기 위해,
객체에서 내부적으로 정의한 행위
수행되는 작업은 외부에서
볼 수 없다
수행 중에 객체의 속성을
바꿀 수 있다.
군대 남
Message :
복부를 향해
주먹을 날림
Method : 날아오는
위치 계산 후 위치
이동하고, 발차기로 대응함
관계 여
새로운 남
[89]
비트교육센터
메소드(Method)(2)
Object
[attribute, method]
수강생1
수강생2
message
객체지향
프로그래밍
수업
강사1
수강생5
수강생3
[90]
수강생4
비트교육센터
클래스(Class)
유사한 특성(행위/구조)을
가지는 일련의 객체들에 대해
그들의 공통적인 구조와 행위를
표현한 개념(Concept)
수강생1
수강생2
B
A
수강생 개념
강사1
강사 개념
B
A
수강생3
수강생5
수강생4
[91]
비트교육센터
인스턴스(Instance)
클래스에 표현된 특성에 임의의 값을
가지고 새롭게 만들어진 객체
수강생1
수강생2
B
A
강사1
수강생 개념
B
A
수강생3
수강생5
수강생4
신규 수강생
[92]
비트교육센터
클래스 계층(Class Hierarchy) (1)
유사한 구조와 행위를 가진 클래스들 간의
개념적 포함 관계를 계층적으로 나타낸 것
상위 클래스는 하위 클래스들에 대한
공통적인 구조와 행위를 소유함
하위 클래스는 자신만의 특별한
특징만을 가진다
온전한 객체를 만들기 위해서는
상위 클래스로부터 공통된 특징을
상속받아야 한다
계층적으로 구성되므로,
하위 클래스는 다시 그 하위 클래스의
상위 클래스로서의 역할을 갖는다
체계적인 개념 관리와 새로운 개념의
추가, 기존 개념의 변경이 쉽다
인간의 사고 방식과 동일한 형태로
현실 세계의 개념을 표현
[93]
비트교육센터
클래스 계층(Class Hierarchy) (2)
수강생1 (회사:P)
수강생2
(학교: A)
수강생
얼굴표정
이해도
B
A
강사1
B
A
수강생3
(회사:Q)
직장인
수강생
수강생5
(학교:B)
회사
학생
수강생
학교
수강생4
[94]
비트교육센터
캡슐화(Encapsulation)
객체 내부에 정의된 것은
외부로부터 감춰진다
메시지를 받은 객체는 내부적으로 메소드를
이용하여 자신의 상태를 변경하지만, 외부에는
수행된 결과를 노출시키지 않을 수 있다
객체 내부의 변경은 다른 객체에
영향을 끼지지 않는다
정보 은닉을 보장해 준다
ME1 : 강의속도 속성 변경
강의 속도 : 빠름/중간/느림
M1 : 강의 내용
M2: 이해도 이미지
강사1
수강생1
[95]
ME1’ : 강의속도와 예제 난이도
속성 변경
강의 속도 : 빠름/느림
예제 난이도 : 높음/낮음
비트교육센터
다형성(Polymorphism)
외부로부터 전달된 메시지에 대해,
관련 객체들이 서로 다르게 반응하는 것
강사
M1 : 강의 내용
수강생
직장인
수강생
M : 머릿속에 그냥
저장한다
학생
수강생
M : 학교에서 배운 내용과
결합하여 가공 저장한다
[96]
비트교육센터
상속(Inheritance) (1)
상위 클래스의 특성이 하위 클래스로
전달되는 행위
온전한 하위 클래스의 표현을 보장하기
위한 메카니즘이다
클래스 계층 구조의 형태에 따라
상속 형태가 달라질 수 있다.
수강생
학생
수강생
직장인
수강생
[97]
비트교육센터
상속(Inheritance) (2)
단일 상속
- 하위 클래스는 한 개의 상위 클래스로부터
개념을 상속 받는다
- 계층 구조가 깊어질수록 개념이 중복되는
경우가 발생한다
탈것
- 식별자
- 생산자
- 매체
- 마력
- 연료 용량
- 연료 종류
모터가 있는
탈것
모터가 없는
탈것
- 원동력
- 이륙 거리
- 최대 고도
모터가 있는
비행기
모터가 없는
비행기
- 이륙 거리
- 최대 고도
[98]
비트교육센터
상속(Inheritance) (3)
다중 상속
- 하위 클래스는 여러 상위 클래스로부터 개념을 상속 받는다
- 계층 구조가 깊어져도 개념의 중복은 적으나, 상속된 개념 간의 충돌이
발생할 수 있다.
탈것
- 식별자
- 생산자
- 매체
비행기
- 이륙 거리
- 최대 고도
- 마력
- 연료 용량
- 연료 종류
모터가 있는
탈것
모터가 없는
탈것
- 원동력
모터가 있는
비행기
모터가 없는
비행기
- 이륙 거리
- 최대 고도
[99]
비트교육센터
Problems of Structural Analysis & Design
Function : A
v1
v5
Function : B
Function : D
v4
v3
Function : E
Function : C
v2
Function : F
[cohesion & coupling]
[100]
비트교육센터
Object-Oriented Methodology (1)
OOA(Object-Oriented Analysis)
도메인 전문가, 사용자, 관리자, 개발자들 간에 만들고자 하는 프로그램에
대한 공통적인 생각을 끄집어 내는 과정
OOD(Object-Oriented Design)
프로그램에 대한 공통적인 생각을 어떻게 구현할 것인지를 계획하는 과정
OOP(Object-Oriented Programming)
설계된 결과에 따라 객체지향 언어를 이용하여 프로그램을 완성하는 과정
[101]
비트교육센터
Object-Oriented Methodology (2)
v1
v5
v4
msg : C, F
v3
v2
Function : A
Function : F
Function : B
Function : C
Function : D
Function : E
[102]
비트교육센터
Chapter
04
클래스
Contents
- 클래스 구조(Class Structure)
- 멤버/멤버함수(Member/Member Function)
- 객체 생성과 소멸(Object Creation & Destruction)
- 내포 클래스(Nested Class)
- 클래스 객체(Class Object)
- 프렌드(Friend)
- 구조체/공용체(Structure/Union)
[104]
비트교육센터
클래스 구조(1)
class class_name
{
public:
type member_name;
return_type member_function_name(argument_list);
private:
type member_name;
return_type member_function_name(argument_list);
};
[105]
비트교육센터
클래스 구조 (2)
class Date
{
int day, month, year;
public:
Date() {}
Date(int d =1, int m=1, int y=1999);
void set(int d, int m, int y)
{ day = d; month =m; year = y; }
bool cmp(const Date&);
void print();
};
Date::Date(int d =1, int m=1, int y=1999) : day(d), month(m), year(y) {}
bool Date::cmp(const Date& d)
{ return (year == d.year && month == d.month && day == d.day ) ?
true : false; }
void Date::print()
{ cout << “( ” << day << “ , ” << month << “ , ”
<< year << “ ) ” << endl; }
[106]
비트교육센터
Member(1)
속성(Attribute)
임의의 객체를 멤버로
정의 가능하다
클래스의 구조를
표현한다
가능한 외부로
노출시키지 않는다
[107]
비트교육센터
Member(2)
#include <iostream.h>
object
class Date
{
31
12
int day, month, year;
// private members
public:
2001
this
void set(int day, int month, int year)
{
객체 자신을 가리키는 포인터
this ->day = day;
특징 : 자신만을 가리킬 수 있다.
용도 : 1. 이름 충돌을 방지.
2. 자기자신을 외부로 전달
Date::month =month;
this->year = year;
}
Data* const this;
};
멤버의 범위를 정해줌으로서,
이름충돌을 막아준다.
[108]
비트교육센터
[109]
비트교육센터
Member Function (1)
메시지와 메소드에 대한
구체화된 표현
객체 내/외부에 대한
서비스 제공
구현 내용은 외부로부터
감춰짐
[110]
비트교육센터
Member Function (2)
멤버 함수의 종류
– 인라인 멤버 함수
컴파일 후 생성된 기계 코드가 다른 함수에 내포되는 함수
프로그램 크기는 커지지만, 속도는 증가
짧은 라인 수를 가진 함수만이 인라인으로 정의함
클래스 내부에 정의되었거나, inline 키워드가 함수 선언부에 붙어있는 함수
– 일반 멤버 함수
분기를 통해서 수행될 수 있는 함수.
프로그램의 크기는 작지만, 잦은 호출은 속도를 저하시킬 수 있음
– 상수 멤버 함수
함수의 몸체에서 멤버 값을 변경할 수 없는 함수.
함수가 멤버 값을 수정해서는 안될 때 유용하게 사용할 수 있음.
함수 선언부 끝에 const 가 붙어 있는 함수 (예: void print() const)
상수 객체는 상수 멤버 함수만을 수행시킬 수 있음.
(예 : const Date obj; 와 같이 객체가 정의되었을 때, obj 에 대해서는 상수 멤버
함수만을 사용할 수 있다.)
[111]
비트교육센터
Member Function (3)
#include <iostream.h>
class Date
{
int day, month, year;
public:
void set(int d, int m, int y) // inline member function
{ day = d; month =m; year = y; }
bool cmp(const Date&) const;
void print() const;
// general constant member function
};
inline bool Date::cmp(const Date& d) const { /* … */ }
// inline constant member function
void Date::print() const
{ /* … */ }
[112]
비트교육센터
[113]
비트교육센터
객체 생성 (1)
void f()
{
Date obj;
}
Date
createMethod() {…}
create
obj
새로운 인스턴스를
만들어 내는 것
생성자 (Constructor)
 인스턴스를 만들어내는 메소드
 클래스가 소유하는 메소드
 객체를 초기화함
객체 생성 과정
 멤버의 생성자로 멤버 객체 생성
 생성자의 몸체를 수행하여 객체 초기화
[114]
비트교육센터
객체 생성 (2)
디폴트 생성자 ( Default Constructor )
Date
void f()
{
Date obj;
}
Date() {
/* 2001년 1월1일로
항상 초기화 */
}
create
obj
 인자를 받지 않으며, 객체를 위한
공간만을 할당해 주는 생성자.
 클래스에 생성자가 하나도 없는 경우,
자동으로 만들어진다
2001
1
1
 객체 생성시 특별한 값을 주고 싶은 경우,
해당 몸체를 가진 함수를 정의할 수 있다
[115]
비트교육센터
객체 생성 (3)
인자를 받는 생성자
Date
void f()
{
create
Date obj(2005,4,5);
}
create
obj
 객체 공간과 함께, 인자로 받은 값을
이용하여 객체를 초기화하는 생성자
 인자의 종류와 개수에 따라 여러 생성자를
생성할 수 있다.
[116]
2005
Date(int y, int m, int d)
{
/* 인자값으로 날짜
설정 */
}
4
5
비트교육센터
객체 생성 (4)
복사 생성자
Date
void f()
{
Date obj(2005,4,5);
Date today = obj;
}
create
today
 동일한 타입의 다른 객체를 인자로 받아,
생성되는 객체를 초기화하는 생성자
 따로 생성하지 않으면, “디폴트 복사 생성자”를
컴파일러가 자동으로 생성해 줌.
 “디폴트 복사 생성자”가 문제가 발생될 경우만
따로 정의하여 사용함.
[117]
2005
Date(const Date& arg) {
/* arg 객체를 원하는
형태로 복사
*/
}
4
5
obj
2005
4
5
비트교육센터
객체 생성 (5)
class Person
{
char* name;
int
age;
얕은 복사 생성자
Person::Person(const Person& p)
{
name = p.name;
age = p.age;
}
public:
person(char* n, int a)
{
name = new char[strlen(n)+1];
strcpy(name,n);
age = a;
};
깊은 복사 생성자
person(const Person& p);
}
Person::Person(const Person& p)
{
name = new char[strlen(p.name)+1];
strcpy(name, p.name);
age = p.age;
}
main()
{
Person hong(“Hong, Gil-Dong”, 23);
Person jang = hong;
}
[118]
비트교육센터
객체 생성 (6)
객체의 배열 생성
Date
void f()
{
Date arr[10];
}
Date() {… }
create
=> 10번 수행
arr
 배열 객체는 디폴트 생성자를 객체 수만큼
호출하여 만듦
 초기화하고자 하는 경우, 초기화 블록을
설정해야 함
[119]
2001 2001 2001
...
2001
1
1
1
...
1
1
1
1
...
1
0
1
2
9
비트교육센터
[120]
비트교육센터
[121]
비트교육센터
[122]
비트교육센터
[123]
비트교육센터
[124]
비트교육센터
객체 소멸 (1)
void f()
{
Date obj;
}
Date
destroyMethod() {…}
destroy
~Date() {… }
obj
생성되었던 객체를
소멸시키는 것
소멸자 (Destructor)
 객체를 소멸시키는 메소드
 클래스가 소유하는 메소드
 객체를 메모리를 반환함
객체 소멸 과정
 소멸자의 몸체를 수행하여 추가 공간 반환
 멤버 객체 소멸자를 통해 객체 소멸
[125]
비트교육센터
객체 소멸 (2)
class Date
{
int d, m, y;
public:
Date(int dd=5, int mm=5, int yy=2005) : d(dd), m(mm), y(yy) {}
~Date() {}
//destructor
};
main()
{
Date arr[10]; //main()함수 종료시 ~Date() 가 10번 수행된다.
}
[126]
비트교육센터
[127]
비트교육센터
내포 클래스
내포 클래스란?
– 다른 클래스 내부에 정의된 클래스
특징
– 클래스의 사용 범위가 포함하는 클래스 내부로 한정된다.
– 정의가 다른 동일한 이름의 클래스를 서로 다른 클래스에 한정함으로써 이름 충돌
을 막는다.
Person
Animal
Date
Date
Person::Date
속성: 년/월/일
Animal::Date
속성 : 년/월/일/시
[128]
비트교육센터
[129]
비트교육센터
클래스 객체 (1)
클래스 객체란?
– 클래스로부터 생성되는 객체(인스턴스)가 아닌 클래스 자신
특징
– 클래스의 모든 객체가 공유할 멤버와 멤버 함수를 갖는다.
– 클래스 자체가 개체로 의미를 가질 때 사용한다.
– static으로 표현한다.
[130]
비트교육센터
클래스 객체 (2)
클래스 멤버
– 클래스 선언 바깥에서 독립적으로 초기화 문장을 작성한다.
– main() 함수 호출 전에 메모리 공간(전역 데이터 공간)에 자리가 마련되고 초기화된
다.
– 클래스 멤버가 public으로 선언된 경우에는 객체(인스턴스)가 생성되기 이전에도 클
래스 멤버를 사용할 수 있다.
클래스 멤버 함수
– 객체에 의해 호출될 필요가 없다.
– 어떤 특정 객체와도 결합하지 않기 때문에, 클래스 멤버(static member)만 사용할
수 있다.
[131]
비트교육센터
[132]
비트교육센터
프렌드
프렌드 함수/클래스
– 어떤 클래스의 Private 멤버를 자유롭게 접근할 수 있는 함수 또는 클래스
특징
– 일방적인 관계일 수 있다.
– 코드가 간결해 지고, 효율적이다.
– 클래스의 캡슐화에 위배되기 때문에 자주 사용하지 않는다.
[133]
비트교육센터
[134]
비트교육센터
클래스와 구조체
class Date
{
int day, month, year;
public:
void set(int d, int m, int y);
bool cmp(const Date&);
void print() const;
};
struct Date
{
void set(int d, int m, int y);
bool cmp(const Date&);
void print() const;
private:
int day, month, year;
};
[135]
비트교육센터
연습문제
정수의 배열을 관리할 수 있는 Array 클래스를 생성하시오.
– 생성자 : 배열의 크기를 정수 값으로 받아서 배열을 생성한다.
– 소멸자
– 특정 위치의 데이터를 가져오는 함수
– 특정 위치의 데이터를 변경하는 함수
– 데이터를 마지막 요소로 추가하는 함수
– 특정 위치의 데이터를 삭제하는 함수
– 배열 데이터 전체를 출력하는 함수
– 배열이 현재 꽉 찼는지 비어있는지를 검사하기 위해 내부적으로 사용하는 함수
[136]
비트교육센터
Chapter
05
상속
클래스 계층구조(Class Hierarchy)
개념(Concept)의 계층 구조
Person
기본 클래스
super class, base class, parent class
Friend
Professor
sub class, derived class, child class
파생 클래스(유도 클래스)
School
[138]
Club
비트교육센터
Why Class Hierarchy? (1)
[예제] 회사를 구성하는 사원들에 대한 클래스 표현
일반사원
직원번호, 이름, 나이,
직원번호, 이름, 나이,
전공, 근무년수, 소속 부서, 월급
비서
전공, 근무년수, 소속 부서,
월급, 담당 임원 이름,
담당 임원 직책
관리사원
직원번호, 이름, 나이,
전공, 근무년수, 소속 부서,
월급, 관리직 등급, 관리하는 사원들
[139]
비트교육센터
Why Class Hierarchy? (2)
[예제] 회사를 구성하는 사원들에 대한 클래스 표현 (cont’d)
– 직원 번호가 0보다 큰 수가 되도록 제한하고,
– 배우자 이름도 같이 넣어보자.
=> 모든 클래스의 수정이 필요하다~!!!
//새로 정의한 클래스
Class NN { /* 자연수 */ };
class 일반사원
{
NN
직원번호;
char 배우자[20];
//...
};
Char 배우자[20];
class 관리사원
{
NN
직원번호;
char 배우자[20];
//...
};
[140]
class 비서
{
NN
직원번호;
char 배우자[20];
//...
};
비트교육센터
Why Class Hierarchy? (3)
[예제] 회사를 구성하는 사원들에 대한 클래스 표현을 수정해보자.
– 공통된 속성과 메소드를 모두 포함하는 상위개념 클래스를 하나 생성
직원번호, 이름, 나이,
사원
일반사원
전공, 근무년수, 소속 부서, 월급
관리사원
비서
관리직 등급,
담당 임원 이름,
관리하는 사원들
담당 임원 직책
[141]
비트교육센터
Why Class Hierarchy? (4)
[예제] 회사를 구성하는 사원들에 대한 클래스 표현 (cont’d)
– 직원 번호가 0보다 큰 수가 되도록 제한하고,
– 배우자 이름도 같이 넣어보자.
=> 이젠 상위의 기본 클래스만 수정하면 된다~!!!
class 사원
{
NN
직원번호;
char 배우자[20];
//...
};
//새로 정의한 클래스
Class NN { /* 자연수 */ };
Char 배우자[20];
[142]
비트교육센터
파생 클래스 객체 생성
특징
–
–
–
파생 클래스는 자신이 상속받은 기본 클래스의 private멤버에 직접 접근할 수 없다.
기본 클래스의 멤버 함수 혹은 생성자를 이용해 접근한다.
파생 클래스의 생성자는 기초 클래스의 생성자를 사용해야 한다.
파생 클래스 객체 생성 과정
1. 파생 클래스 생성시 기본 클래스의 생성자를 먼저 실행한다.
• 파생 클래스의 생성자에서 기본 클래스의 생성자가 호출되도록 프로그램한다.
• 기본 클래스의 생성자 호출이 생략되었다면 디폴트 기초 클래스 생성자를 사
용한다.
2. 파생 클래스의 생성자가 실행된다.
• 파생 클래스의 생성자에서는 새로 추가된 멤버들을 초기화해야 한다.
[143]
비트교육센터
파생 클래스 객체 소멸
파생 클래스 객체 소멸 과정
1. 파생 클래스 소멸자가 먼저 실행된다.
•
파생 클래스 생성자에 의해서 동적으로 할당된 메모리가 있다거나 정리작업이
필요한 경우에 반드시 파생 클래스 소멸자가 명시적으로 정의되어야 한다.
2. 기본 클래스의 소멸자가 나중에 실행된다.
•
파생 클래스 객체 중 기본 클래스와 관련된 부분은 기본 클래스 소멸자를 통해
서 정리작업이 이루어진다.
[144]
비트교육센터
protected 접근제한 (1)
클래스 계층 구조에서의 접근 제한
class 사원
{
private:
int 직원번호;
char 이름[20];
int 나이;
//...
public:
사원();
~사원();
getEmpNo();
// 기타 멤버 함수들
};
직원번호 멤버
: 사원 클래스의 private영역에 소속
관리사원 클래스의 직원번호
: 직원번호 멤버에 직접 접근할 수
없으며, getEmpNo()과 같은 멤버
함수를 통해야 한다.
→ 불편하다.
새로운 접근 모드의 필요하다!!
→ “protected” 접근 제한
[145]
비트교육센터
protected 접근제한 (2)
클래스(X)로의 접근 가능 영역
클래스(X)
멤
버
함
수
자신의 프렌드에서
접근 가능
private
section
파생 클래스(Y)의
멤버 함수와 프렌드에서
접근 가능
protected
section
임의의 다른 함수
(클래스 외부)에서
접근 가능
public
section
[146]
비트교육센터
[147]
비트교육센터
[148]
비트교육센터
상속 유형(Inheritance Type)
파생 클래스 정의시 상속의 유형
Class B1: public A
private
Class A
private
protected
public
protected
public
Class B2 : protected A
Class C : public B2
private
private
protected
protected
public
public
Class B3 : private A
Class D : public B3
private
private
protected
protected
public
public
[149]
비트교육센터
기본클래스와 파생클래스의 관계
1. 파생 클래스 객체는 기본 클래스 메서드를 사용할 수 있다.
2. 기본 클래스를 가리키는 포인터와 기본 클래스에 대한 참조 타입은 명시적 데
이터형 변환 없이도 파생클래스 객체를 가리키거나 참조할 수 있다.
3. 파생 클래스를 가리키는 포인터와 파생 클래스에 대한 참조 타입은 기본 클래
스 객체를 가리키거나 참조할 수 없다.
[150]
비트교육센터
가상 함수(Virtual Function) (1)
[예제] 우리 회사 사원들에 대한 정보를 배열로 관리해보자.
– 일반사원과 관리사원, 비서 서로 다른 클래스 유형이 세가지가 있으므로 배열을 세
가지로 나누어 관리해야 하는가?
일반사원 emp[100];
관리사원 mgr[100];
비서 sec[100];
//모든 사원들에 대한 정보를 출력하라
void printall()
{
for (int i=0; i<empind; i++) emp[i].print();
for (int j=0; j<mgrind; j++) mgr[j].print();
for (int k=0; k<secind; k++) sec[k].print();
}
[151]
비트교육센터
가상 함수(Virtual Function) (2)
[예제] 우리 회사 사원들에 대한 정보를 배열로 관리해보자. (cont’d)
– 일반사원, 관리사원, 비서 세가지 클래스의 기본 클래스인 사원 클래스 객체를 가리
킬 수 있는 배열을 만들자.
사원* emps[300];
//모든 사원들에 대한 정보를 출력하라
void printall()
{
for (int i=0; i<ind; i++) emps[i]->.print();
}
[152]
비트교육센터
가상 함수(Virtual Function) (3)
[예제] 우리 회사 사원들에 대한 정보를 배열로 관리해보자. (cont’d)
– 사원 클래스에 각 타입을 구분할 수 있는 멤버를 추가하여 각 객체의 종류가 일반사
원, 관리사원, 비서 세가지 클래스 중 어디에 해당하는지 찾을 수 있도록 한다.
사원* emps[300]; //사원 클래스에 emptype멤버 추가
// enum Etype {EMP, MGR, SEC};
// Etype emptype;
void printall()
{
for (int i=0; i<ind; i++) {
switch(emps[i]->emptype){
case EMP: (일반사원*)emps[i]>print(); break;
case MGR: (관리사원*)emps[i]>print(); break;
case SEC: (비서*)emps[i]>print();
break;
}
}
[153]
비트교육센터
가상 함수(Virtual Function) (4)
가상함수란?
– 메시지 다형성 보장을 위한 것으로, 가상함수가 정의된 클래스의 파생 클래스에 이
를 재정의한 함수가 있을 수 있다는 것을 알려줌.
– 실행 시점에 동적으로 자신의 타입에정의된 함수를 부르도록 함.
– 함수의 선언은 동일해야 함(함수이름, 인자 타입과 개수, 리턴 타입)
사원
일반사원
관리사원
void print()
{ /* ....... */ };
[154]
virtual void print() {/* ....... */ };
비서
void print()
{ /* ....... */ };
비트교육센터
[155]
비트교육센터
[156]
비트교육센터
[157]
비트교육센터
가상 함수(Virtual Function) (5)
가상함수 사용시 주의사항
– 기본 클래스의 멤버 함수가 파생 클래스에서 다시 정의되는 경우에는 가상함수로
선언하는 것이 일반적이다.
– 멤버 함수가 객체에 의해 호출되지 않고 참조나 포인터에 의해 호출되는 경우가 있
다면 해당 멤버 함수를 가상함수로 선언하는 것이 좋다.
– 기본 클래스에서 가상 함수로 정의하려는 함수가 오버로딩 되어있다면, 오버로딩
된 모든 버전에 대하여 파생클래스에서 재정의하여야 한다.
(한가지 버전만 재정의하게 되면, 나머지 버전들은 은닉되어 사용할 수 없게 된다.)
– 프렌드 함수는 가상함수로 선언할 수 없다.
[158]
비트교육센터
가상 소멸자(Virtual Destructor)
가상 소멸자
– 가상 함수를 써야 하는 경우라면, 각 개체들이 소멸될 때에도 올바르게 정리되기 위
해서는 소멸자를 가상 소멸자로 선언해야 한다.
(명시적인 소멸자가 필요없는 기본 클래스일지라도 가상 소멸자를 제공해야 한다.)
void f()
{
사원* emp = new 관리사원(“홍길동”);
// … ...
delete emp;
}
관리사원 객체에서 파생시에 추가적으로
사용된 메모리가 있었다면 소멸시 반드시 정리
작업이 이루어져야 한다.
사원 클래스의 소멸자가 가상이 아니라면
: delete 작업시에 사원 클래스의 소멸자가 불
리므로 올바른 정리가 이루어지지 못한다.
 반드시 사원 클래스의 소멸자는 가상으로
선언되어야 한다.
[159]
비트교육센터
추상화 클래스(Abstract Class) (1)
추상화 클래스(Abstract Class or Abstract Base Class)
– 구체화된 객체를 생성할 필요가 없는, 추상적인 개념만을 표현하는 클래스
사원
일반사원
관리사원
사원 클래스는 회사내의
사원들에 대한 공통된
멤버와 멤버 함수를
표현하지만, 객체를 생성할
필요가 없다.
비서
[160]
=> 추상화 클래스로 표현~!
비트교육센터
추상화 클래스(Abstract Class) (2)
추상화 클래스 생성 방법
– 하나 이상의 가상함수를 몸체가 없는 순수 가상 함수(pure virtual function)로 선언
한다.
– 파생 클래스에서는 기본클래스의 순수 가상 함수를 반드시 재정의해야 객체를 생성
할 수 있다.
– 순수 가상 함수 : 함수의 몸체가 0인 가상 함수
(예)
virtual void print() = 0 ;
이 경우, print()함수는 클래스 선언부에 몸체를 가질 수 없다.
그러나 .cpp파일에 몸체를 정의할 수는 있다.
[161]
비트교육센터
[162]
비트교육센터
다중 상속(Multiple Inheritance) (1)
다중 상속
– 한 클래스가 여러 다른 클래스를 상속받는 것
다중 상속의 문제
– 별개의 두 기본 클래스로부터 이름은 같지만 서로 다른 멤버함수를 상속 받을 수 있
다.
– 서로 관련된 클래스들로부터 상속받음으로써 특정 클래스가 다중 상속 될 수 있다.
다중 상속의 유형
– 서로 다른 기본 클래스를 가지는 클래스들을 상속하는 것
– 중복되는 기본 클래스의 다중 생성
– 중복되는 기본 클래스의 단일 생성
[163]
비트교육센터
다중 상속(Multiple Inheritance) (2)
상속유형 1 - 서로 다른 기본 클래스를 가진 클래스들의 상속
사원
임시직
일반사원
[164]
관리사원
비서
컨설턴트
임시직 비서
비트교육센터
다중 상속(Multiple Inheritance) (3)
상속유형 2 - 중복되는 기본 클래스의 다중 생성
운동선수
축구선수
야구선수
축구야구선수
[165]
비트교육센터
다중 상속(Multiple Inheritance) (4)
상속유형 3 – 가상상속 : 중복되는 기본 클래스의 단일 생성
- 식별자
- 생산자
- 매체
탈것
비행기
- 마력
모터 있는 탈것 - 연료용량
- 연료종류
모터 없는 탈것
- 원동력
- 이륙거리
- 최대고도
모터 있는 비행기
모터 없는 비행기
[166]
비트교육센터
다중 상속(Multiple Inheritance) (5)
가상 기본 클래스(virtual base class)와 생성자
– 가상 기본 클래스 : 파생 클래스들에게 가상(virtual)으로 상속되는 기본 클래스
– 가상 기본 클래스가 존재하면 파생 클래스들에게 생성자 작성시 주의해야 한다.
class 운동선수
{
운동선수(char* name);
};
class 축구선수: virtual public 운동선수
{
축구선수(char* name, int goal):운동선수(name) {......}
};
class 야구선수: virtual public 운동선수
{
야구선수(char* name, int homerun):운동선수(name) {......}
};
class 축구야구선수: public 축구선수
{
축구야구선수(char* name, int goal, int homerun)
: 축구선수(name, goal),야구선수(name,homerun) {......}
};
[167]
가상상속
비트교육센터
다중 상속(Multiple Inheritance) (6)
가상 기본 클래스(virtual base class)와 생성자 (cont’d)
– 잠재적인 충돌을 피하기 위하여 기본 클래스가 가상일 경우에는 중간 단계에서 가
상 기본 클래스로 정보를 자동으로 전달하여 생성자를 수행시키는 기능을 정지시킨
다.
– 다중 상속에 의한 파생 클래스 생성자에서 가상 기본 클래스의 생성자를 수행시키
고 싶을때에는 명시적으로 생성자를 호출하여야 한다.
//앞의 축구야구선수 클래스 생성자의 수정
class 축구야구선수: public 축구선수
{
축구야구선수(char* name, int goal, int homerun)
: 운동선수(name), 축구선수(name, goal),야구선수(name,homerun) {......}
}
[168]
비트교육센터
다중 상속(Multiple Inheritance) (7)
다중 상속된 클래스에서의 멤버 함수 호출
– 방법1 : 다중 상속으로 인하여 같은 멤버 함수가 둘 이상 존재할 경우, 범위 지정 연
산자(::)를 사용하여 모호성을 피한다.
– 방법2 : 다중 상속으로 인하여 같은 멤버 함수가 둘 이상 존재할 경우, 파생 클래스
에서 재정의한다.
void 축구선수::print() {......}
void 야구선수::print() {......}
int main(void)
{
축구야구선수 park (“ChanHo”, 10, 20);
park.print(); //ambiguous ~!!
park.축구선수::print(); //ok 방법1.소속클래스를 밝힌다.
park.야구선수::print(); //ok
}
[169]
비트교육센터
RTTI (1)
RTTI(RunTime Type Information)
– 실시간 데이터 타입 정보
– 실행시간에 각 객체들이 가진 타입 정보
목적
– 프로그램이 실행 도중에 객체의 데이터 타입을 결정하는 표준 방법을 제공하는 것
– 동작 중인 객체의 실제 타입 정보를 즉각적으로 얻어, 필요한 연산을 수행하도록 할
수 있다.
– 동종의 타입으로의 실시간 타입 변환을 가능하게 하여 유연성있는 프로그램을 구성
할 수 있다.
주요 구성 요소
– type_info 클래스와 typeid 연산자
– dynamic_cast 타입 변환 연산자
[170]
비트교육센터
RTTI (2)
type_info 클래스
– 타입에 기반한 기본적인 정보를 제공하는 클래스로서, 구현 환경에 따라 달라질 수
있다.
– typeinfo 헤더파일에 정의되어 있다.
class type_info {
public:
virtual ~type_info();
int operator == (const type_info& rhs) const; //== 연산자 오버로딩
int operator != (const type_info& rhs) const; // != 연산자 오버로딩
int before(const type_info& rhs) const;
const char* name() const; //타입의 이름을 반환하는 멤버 함수
const char* raw_name() const;
private:
...
};
[171]
비트교육센터
RTTI (3)
typeid 연산자
– 전달인자의 종류 : 클래스의 이름 or 객체로 평가되는 식
– 인자로 주어지는 객체의 타입 이름이나 수식의 결과 타입에 대한 type_info 정보를
제공한다.
const type_info& typeid(type_name) throw(bad_typeid);
const type_info& typeid(expression);
[172]
비트교육센터
RTTI (4)
dynamic_cast 연산자
– 인자로 주어진 객체의 실제 타입을 참조하여 원하는 타입으로 타입변환 하는 함수
dynamic_cast<T*>(pointer)
dynamic_cast<T&>(object)
특징
– 대응되는 타입으로의 변환이 불가능한 경우
포인터 타입이면 ->null을 반환
참조 타입이면 -> bad_cast 에외를 발생시킴
– downcast, upcast, crosscast 모두 허용함
[173]
비트교육센터
[174]
비트교육센터
데이터 타입 변환 연산자
추가적인 데이터 타입 변환 연산자
– dynamic_cast
– const_cast
: 어떤 값을 const나 volatile로 또는 그 반대로 변환하는 연산자
– static_cast
: 기본 클래스를 파생클래스로 변환하여 사용하기 위한 연산자로 언제나 유효한
것은 아니다.
– reinterpret_cast
: 위험한 데이터 타입 변환을 하기 위한 연산자
: 시스템 의존적인 low level 프로그래밍에서 주로 사용
dynamic_cast <type_id> (expression)
const_cast <type_id> (expression)
static_cast <type_id> (expression)
reinterpret_cast <type_id> (expression)
[175]
비트교육센터
Chapter
06
연산자 오버로딩과 자동 변환
연산자 오버로딩
목적
– Built-in 타입에 대해 사용할 수 있었던 연산자들을 사용자 정의 데이터 타입에 대해
서도 동일한 이름으로 동일한 연산을 수행하도록 하여, 프로그램을 이해하기 쉽고
간결하게 만들자는 것
void func()
{
int i=10, j=20, k;
k = i + j * i;
}
A set of
operators
int
Built-in type
복소수
A set of member
functions
User-defined type
void func()
{
복소수 i=10, j=20, k;
k.assign(i.add(j.multiply(i)));
}
이해하기 어렵고, 오류 발생 가능성 높다.
[177]
비트교육센터
오버로딩 가능 연산자들
오버로딩 가능 연산자들
+
-
*
/
%
^
&
|
~=
!
=
<
>
<=
>=
==
!=
+=
-=
*=
/=
%=
^=
&=
|=
<<=
>>=
<<
>>
&&
||
++
--
,
->*
->
()
[]
new
delete
오버로딩 불가능 연산자들
멤버 연산자
.
멤버 지시 포인터 연산자
.*
범위 지정 연산자
::
조건 연산자
?:
RTTI 연산자
typeid
데이터형 변환연산자
const_cast, dynamic_cast, static_cast
[178]
비트교육센터
예제를 위한 복소수 클래스 선언
Complex class using member functions
class Complex {
double re, im;
public:
Complex(double r, double i) : re(r), im(i) {}
Complex add (const Complex&) const;
Complex multiply (const Complex&) const;
Complex& post_pp(); // 후위 ++
Complex& pre_pp(); // 전위 ++
Complex& assign(const Complex&) const;
void print() { cout << "Real : " << re << " , " << "Imaginary : " << im << endl; }
// .…
};
[179]
비트교육센터
Binary Operator : +
복소수의 합을 구하는 함수를 작성하자.
Complex Comoplex::add (const Complex &c) const
{
Complex sum;
sum.re = re + c.re;
sum.im = im + c.im;
return sum;
}
Complex Comoplex::operator+ (const Complex &c) const
{
Complex sum;
sum.re = re + c.re;
sum.im = im + c.im;
return sum;
}
[180]
비트교육센터
Binary Operator : *
복소수의 곱을 구하는 함수를 작성하자.
Complex Comoplex:: multiply (const Complex &c) const
{
Complex mul;
mul.re = re * c.re;
mul.im = im * c.im;
return mul;
}
Complex Comoplex::operator* (const Complex &c) const
{
Complex mul;
mul.re = re * c.re;
mul.im = im * c.im;
return mul;
}
[181]
비트교육센터
Unary Operator : ++(전위)
실수부와 허수부 각각을 1 증가시키는 증가 연산자를 작성하자.
– 전위 증가 연산자 : (예)++a;
Complex& Comoplex:: pre_pp()
{
++re;
++im;
return *this;
}
Complex Comoplex::operator++ ()
{
++re;
++im;
return *this;
}
[182]
비트교육센터
Unary Operator : ++(후위)
실수부와 허수부 각각을 1 증가시키는 증가 연산자를 작성하자.
– 후위 증가 연산자 : (예) a++;
Complex Comoplex:: post_pp()
{
Complex tmp;
tmp.re = re;
tmp.im = im;
re++;
im++;
return tmp;
}
Complex Comoplex:: operator++(int a)
{
Complex tmp;
tmp.re = re;
tmp.im = im;
re++;
im++;
return tmp;
}
[183]
dummy argument
비트교육센터
<< operator
복소수가 print() 함수를 통해서가 아니라 바로 출력될 수 있도록 오버로딩 하자.
ostream& operator<< (ostream& os, Complex& c) const
{
os << "Real : " << c.re << " , " << "Imaginary : " << c.im;
return os;
}
– 출력 시에 osteam객체가 연산자의 왼쪽에 오고, 출력 대상인 사용자 정의 데이터
타입이 오른쪽에 와야 하므로 전역 함수로 오버로딩 한다.
– 단일 대상 출력인 경우 ostream객체를 반환할 필요가 없지만, 연속 출력의 경우에
는 반드시 ostream객체를 반환하여야 한다.
예) 단일 출력 : cout << c1;
연속 출력 : cout << c1 << “, “ << c2 << endl;
[184]
비트교육센터
Subscripting Operater : []
사용자 정의 데이터형의 배열 요소에 접근할 때 사용하는 []연산자를 작성하자.
class Student
{
Jumsu myjumsu[5];
int ind;
char name[20];
public:
Student(char* nm):ind(0){strcpy(name, nm);};
void savegrade(const Jumsu& j);
void print() const;
Jumsu& operator[] (int);
};
– 연관 매핑[Associative Mapping)에 사용한다.
[185]
비트교육센터
[186]
비트교육센터
Assignment Operator (1)
복소수를 복소수에 대입하는 연산자를 오버로딩 해보자.
Complex Comoplex::assign (const Complex &c) const
{
re = c.re;
im = c.im;
return *this;
}
Complex Comoplex::operator= (const Complex &c) const
{
re = c.re;
im = cim;
return *this;
}
[187]
비트교육센터
Assignment Operator (2)
디폴트 대입 연산자
– 사용자 정의 데이터 타입에 대해 대입 연산자가 오버로딩 되지 않은 자동으로 삽입
되어 실행된다.
– 디폴트 복사 생성자와 마찬가지로 멤버 변수 대 멤버 변수를 복사하는 기능을 지닌
다.
– 메모리 유출과 얕은 복사라는 문제점이 있으므로 메모리를 동적으로 할당하여 사용
하는 사용자 정의 데이터 타입인 경우에는 깊은 복사가 이루어지도록 명시적으로
대입 연산자를 오버로딩 하여야 한다.
[188]
비트교육센터
De-referencing Operator
Dereferencing 연산자(->)를 오버로딩 하여 보자.
class Ptr {
X* operator->(); //언제나 반환값이 포인터가 된다.
};
void f(Ptr p) {
p->m = 7;
// 위의 내용은 (p.operator->())->m = 7 과 같다.
}
– 단항, 후위 연산자
– 포인터의 역할과 추가적인 작업을 수행하는 용도로 사용된다.
– ‘Smart Pointer’구현에 적합하다.
[189]
비트교육센터
Conversion Operator (1)
데이터 타입 변환
int
Complex
두 타입간의 형 변환이 필요할 때,
어떻게 지원해야 하는가?
기존 Built-in 타입 간에는 자동 타입 변환이 가능하다.
사용자 정의 데이터 타입도 자동 변환이 되도록 하기 위해서는
변환 연산자를 재정의 해야한다. !!!
[190]
비트교육센터
Conversion Operator (2)
규칙 1.
– C++에서 하나의 전달인자를 취하는 생성자는 그 전달인자 데이터 타입의 값을 클
래스 타입으로 변환하는 길을 제공한다.
class Complex {
double re, im;
public:
Complex(double r, double i) : re(r), im(i) {}; // 2개의 전달인자를 받는 생성자
Complex(double r) : re(r), im(0) {}; //double타입 1개의 전달인자를 받는 생성자
Complex(int r) : re(r), im(0) {}; // int타입 1개의 전달인자를 받는 생성자
};
int -> Complex 자동 타입 변환 가능
double -> Complex 자동 타입 변환 가능
[191]
비트교육센터
Conversion Operator (3)
규칙 2.
– 단 하나의 전달인자를 갖는 생성자가 있을지라도 해당하는 생성자가 explicit 키워
드로 제한된 경우에는 명시적인 데이터형 변환만 할 수 있다.
class Complex {
double re, im;
public:
Complex(double r, double i) : re(r), im(i) {}; // 2개의 전달인자를 받는 생성자
Complex(double r) : re(r), im(0) {}; //double타입 1개의 전달인자를 받는 생성자
explicit Complex(int r) : re(r), im(0) {}; // int타입 1개의 전달인자를 받는 생성자
};
int -> Complex 자동 타입 변환 불가능
double -> Complex 자동 타입 변환 가능
[192]
비트교육센터
Conversion Operator (4)
규칙 3.
– Conversion Function을 정의하여 사용자 정의 데이터 타입을 다른 타입으로 변환
하도록 할 수 있다.
class Complex {
double re, im;
public:
Complex(double r) : re(r), im(0) {}; //double타입 1개의 전달인자를 받는 생성자
Complex(int r) : re(r), im(0) {}; // int타입 1개의 전달인자를 받는 생성자
operator int() { return (int)re; }; //데이터 타입 이름이 함수의 이름이 된다.
operator double() {return re; };
};
Complex -> int 타입 변환 가능
Complex -> double 타입 변환 가능
[193]
비트교육센터
Conversion Operator (5)
주의할 점
– 변환 함수는 클래스의 메서드이어야 한다.
– 변환 함수는 전달인자를 가질 수 없다.
– 변환 함수는 반환 데이터 타입을 가지지 않는다.
– 변환 과정에서 데이터의 손실이 발생할 수 있다.
– 생성자에 의한 자동 변환이나 변환 함수를 사용하는 경우에나 모두 함수 선택에 있
어서 모호한 상황이 발생하면 오류가 발생한다.
[194]
비트교육센터
사용 금지를 위한 오버로딩
class X {
private:
void operator=(const X&);
void operator&();
void operator,(const X&);
};
void f(X a, X b)
{
a=b;
// error:operator=private
&a;
// error: operator& private
a,b;
// error:operator,private
}
[195]
비트교육센터
[196]
비트교육센터
[197]
비트교육센터
[198]
비트교육센터
[199]
비트교육센터
연습문제(1)
문자열을 다룰 수 있는 String 클래스를 생성하시오.
– 생성자 : (1) 인자가 전혀 없는 생성자
(2) 문자열 인자를 하나 받는 생성자
(3) 복사 생성자
– 소멸자
– 대입연산자 오버로딩(=)
– 비교 연산자 오버로딩(<, >, ==, !=)
– 배열 연산자 오버로딩([])
: 문자열 내 특정 위치의 문자 한개를 반환하는 연산자와 대입시키는 연산자
– 입출력 연산자 오버로딩(<<, >>)
– 문자열의 길이를 반환하는 함수
[200]
비트교육센터
연습문제(2)
정수의 배열을 관리하는 Array 클래스를 “4장. 클래스”장의 연습문제에서 작성
하였다. 그 중 연산자와 관련된 기능을 수행하는 멤버 함수를 연산자 오버로딩으
로 수정하시오.
– 특정 위치의 데이터를 가져오는 함수
– 특정 위치의 데이터를 변경하는 함수
– 배열 데이터 전체를 출력하는 함수
[201]
비트교육센터
Chapter
07
템플릿
클래스템플릿(Class Template) (1)
int 타입 데이터를 관리하는 스택(stack) 클래스를 만들어보자.
– 스택 : LIFO(Last Input, First Out)특징을 지니는 자료구조. 마지막에 들어간(push)
데이터가 가장 먼저 나오게되는(pop) 형식의 저장구조를 말한다.
class Stack
{
private :
int data_arr[10]; //데이터 갯수 최대 10개인 스택 정의
int top;
bool is_empty() const {return top<=0;};
bool is_full() const {return top>=10;};
public :
Stack():top(0){};
~Stack(){}
bool push(const int&); //스택에 데이터를 저장한다.
bool pop(int&); //스택에서 최상위 데이터를 꺼내온다.
};
[203]
비트교육센터
클래스템플릿(Class Template)(2)
앞의 int 타입 스택구조를 보고 char타입 스택 구조 클래스를 정의하여 보자.
– 방법1
: int 타입 스택 클래스 코드를 전부 복사한 후 char 타입 자료를 처리할 수 있도
코드를 수정한다.
: 단점
- 데이터 타입을 변경해야 할 때마다 계속해서 헤더 파일을 바꾸어 주어야
한다.
- 같은 종류의 멤버와 멤버 함수를 갖고, 데이터 타입만 다른 클래스에 대해
중복 코딩 되어야 하며, 이는 유지보수에 어려움을 낳는다.
– 방법2
: int 타입 스택 클래스를 보고 실제 사용시 필요한 데이터 타입만 인자로
넘겨서 처리할 수 있는 템플릿을 생성시킨다.
[204]
비트교육센터
클래스템플릿(Class Template)(3)
클레스 템플릿(Class Template)
– 인자를 받아서 새로운 클래스를 생성해 주는 메타 클래스
– 클래스 템플릿 인자 : 데이터 타입, 포인터, 상수 값, 함수 등일 올 수 있다.
템플릿
인자
클래스
템플릿
[205]
생성된
클래스들
비트교육센터
클래스템플릿(Class Template)(4)
클래스 템플릿의 기본 구조
template <typename T>
class ClassName
{
private :
T member1;
T member2;
//클래스 템플릿에서 사용할 멤버 선언
public :
ClassName();
~ClassName(){}
void MFunction1(T&, T&);
T MFunction2();
//외부에서 접근 가능한 멤버함수들에 대한 선언 및 정의
};
[206]
비트교육센터
클래스템플릿(Class Template)(5)
이제 앞의 int 타입 스택클래스를 템플릿으로 바꾸어보자.
template <typename T>
class Stack
{
private :
T data_arr[10]; //데이터 갯수 최대 10개인 스택 정의
int top;
bool is_empty() const {return top<=0;};
bool is_full() const {return top>=10;};
public :
Stack():top(0){};
~Stack(){}
bool push(const T&); //스택에 데이터를 저장한다.
bool pop(T&); //스택에서 최상위 데이터를 꺼내온다.
};
[207]
비트교육센터
클래스템플릿(Class Template)(6)
클래스 템플릿의 사용
– 템플릿을 사용할 때에는 인자로 넘겨주어야 할 데이터 타입 혹은 상수 값 등이 명시
되어야 한다.
– 사용 예
Stack 클래스의 사용 : Stack mystack;
Stack 클래스 템플리의 사용 :
//템플릿에서 처리하는 데이터가 각각 int, char 타입임을 인자로 전달하였다.
Stack<char> mystack1;
Stack<int> mystack2;
[208]
비트교육센터
클래스템플릿(Class Template)(7)
상수 값을 템플릿 인자로 받는 클래스 템플릿
– Stack의 최대 크기를 실행 시 동적으로 결정될 수 있도록 데이터 타입과 상수 값을
인자로 가지는 템플릿으로 수정하자.
template <typename T, int s>
class Stack
{
private :
T* data_arr;
int size;
int top;
bool is_empty() const {return top<=0;};
bool is_full() const {return top>=10;};
public :
Stack(); ~Stack();
bool push(const T&);
bool pop(T&);
};
[209]
비트교육센터
[210]
비트교육센터
클래스템플릿(Class Template)(8)
클래스 템플릿의 특수화(Specialization)
– 특정 데이터 타입이 전달되었을 때에만 호출이 되도록 클래스 템플릿 특수화 시켜 정
의할 수 있다.
– template <typename T> class Stack {};
: 어느 데이터 타입에나 상관없이 부르게 되는 포괄적인 클래스 템플릿
–
template <> class Stack<char*> {};
: 특별히 char* 타입의 데이터들이 Stack 클래스 템플릿 인자로 전달되었을 때에만
사용되는 특수화된 템플릿
: 이 때, 특별한 타입에만 적용되어야 하는 기능 들이 재정의 되거나 추가될 수
있다.
[211]
비트교육센터
[212]
비트교육센터
[213]
비트교육센터
클래스템플릿(Class Template)(9)
클래스 템플릿의 상속 (cont’d)
– 특징 1.
: 일반 클래스로부터 클래스 템플릿으로의 상속이 가능하다.
class Slink {......};
template <typename T>
class Tnode : public Slink { T val; };
main() {Tnode<int> mynode;}
– 특징2.
: 클래스 템플릿 간의 상속이 가능하다.
template <typename T> class vector {......};
template <typename T> class Vec: private vector<T> {......};
[214]
비트교육센터
클래스템플릿(Class Template)(10)
클래스 템플릿의 상속
– 특징 3.
: 일반 클래스나 클래스 템플릿은 템플릿을 멤버로 가질 수 있다.
template <typename Scalar> class Complex {
Scalar re, im;
public:
template<typename T> Complex(const Complex<T>& c)
: re(c.re), im(c.im) {}
//......
};
Complex<float> cf(0,0);
Complex<double> cd = cf;
이 경우에는 scalar : double, T: float가 된 것
[215]
비트교육센터
클래스템플릿(Class Template)(11)
클래스 템플릿의 상속
– 특징 4.
: 템플릿 인자간의 계층 관계는 템플릿 정의 시 무의미해진다.
– 특징 5.
: 타입 변환 연산자를 정의하여 서로 다른 템플릿 인자에 대한 타입 변환 작업을
가능하게 할 수 있다.
[216]
비트교육센터
함수 템플릿(Function Template)(1)
int 타입 두개의 인자를 서로 바꾸는 Swap함수를 정의해보자.
void Swap(int &n, int &m)
{
int temp;
temp = n;
n = m;
m = temp;
}
앞의 int 타입 Swap함수를 보고 char타입 Swap함수를 정의하자.
– 복사를 하여 int라는 글자들을 모두 char로 수정할 것인가?
– 클래스 템플릿과 마찬가지로 실제 함수 실행시 필요한 데이터 타입만 인자로 넘겨
주어서 처리할 수 있는 템플릿을 생성하여 사용하자.
[217]
비트교육센터
함수 템플릿(Function Template)(2)
함수 템플릿(Function Template)
– 인자를 받아 동일한 기능의 새로운 함수를 생성해 주는 함수
– 함수 템플릿 인자 : 데이터 타입만 올 수 있다.
템플릿
인자
함수
템플릿
[218]
생성된
함수들
비트교육센터
함수 템플릿(Function Template)(3)
이제 앞의 int 타입 Swap함수를 템플릿으로 바꾸어보자.
template <typename T>
void Swap(T &n, T &m)
{
T temp;
temp = n;
n = m;
m = temp;
}
Swap 함수 템플릿의 사용
Swap<int>(n1, n2); //명시적으로 처리하려는 데이터 타입을 인자로 넘김
Swap(ch1, ch2); //명시적으로 데이터 타입을 주지 않으면 함수의 매개변수의
//타입으로 유추하여 생성한다.
[219]
비트교육센터
함수 템플릿(Function Template)(4)
Swap함수 템플릿의 데이터 타입으로 사용자 정의 데이터 타입 객체를 사용하자.
Class Person
{
private :
char* name; char* phoneno;
public :
Person(); ~Person();
void print() const;
};
int
age;
– 위의 Person 데이터 타입 객체를 Swap함수의 데이터로 넘겨서 실행하여보자.
아무런 문제 없이 수행이 잘 될까?
[220]
비트교육센터
[221]
비트교육센터
[222]
비트교육센터
[223]
비트교육센터
함수 템플릿(Function Template)(5)
함수 템플릿의 특수화(Specialization)
– template <typename T> void Swap(T& a, T& b)
: 어느 데이터 타입이나 관계없이 부르도록 하는 포괄적인 템플릿
–
template <char> void Swap(char& a, char& b)
: 특별히 char 타입의 데이터들이 Swap함수의 인자로 전달되었을 때에만 사용
되도록 하는 특수화된 템플릿
: 이 때, 템플릿 인자의 데이터 타입과 Swap함수의 매개변수의 데이터 타입이 같은
경우에는 템플릿 인자의 데이터 타입을 생략할 수 있다.
즉, template <> void Swap(char& a, char& b) 혹은
template <> void Swap<char>(char& a, char& b) 도 가능한 표기법이다.
[224]
비트교육센터
[225]
비트교육센터
함수 템플릿(Function Template)(6)
특징1
– 템플릿 인자가 템플릿 함수 인자에서 유추될 수 없는 경우에는, 어떤 템플릿 인자를
받을 것인지 명시적으로 표현해야 한다.
– 유추 가능한 경우에는 명시적으로 데이터 타입을 표현하지 않아도 된다.
특징2
– 동일한 이름을 가진 여러 함수 템플릿과 일반 함수들이 정의될 수 있다.
: 일반적인 함수와 마찬가지로 함수 템플릿도 오버로딩 되며, 이 때 매개변수로 확
실하게 구분이 되어야 한다.
– 동일한 이름을 갖는 함수가 여러개일 때 우선순위 규칙에 의해 올바른 함수를 선정
하여 부르게 된다.
특징3
– 경우에 따라서는 함수 템플릿 인자를 명시적으로 기술하여야 모호성을 제거하고 실
행 가능하게 된다.
[226]
비트교육센터
연습문제
배열 관리 템플릿(Tarray)을 작성하시오.
– 정수의 배열을 관리하는 Array 클래스를 “6장. 연산자 오버로딩”장의 연습문제에서
작성하였다. 그 Array클래스를 int타입 뿐 아니라 다른 데이터 타입으로도 사용할 수
있도록 템플릿으로 수정하시오.
[227]
비트교육센터
Chapter
08
예외(Exceptions)
전통적인 방식의 예외 처리 방식
전통적인 예외(에러)의 처리 방식
– 프로그램의 종료(abort()호출)
– 에러 코드 값의 반환
– 정상적인 값을 반환토록 하여 정상적으로 프로그램을 진행하거나 비정상적으로 동
작시킴
– 에러 처리 함수 호출
문제점
– 정상적인 프로그램 수행 코드와 에러 처리 코드의 경계가 불분명함
– 에러 상황에 대한 정보를 얻기 어려움
– 에러에 대한 체계적인 관리 방법 부재
[229]
비트교육센터
예외 처리 방식 (1)
C++의 예외 처리 방식
step1.
step2.
step3.
step4.
예외를
예외를
예외를
포착된
정의(?)하고
발생시키고
포착하고
예외를 처리한다.
예외 처리 문법 구조
void f()
{
try {
EGC(); //error generation (function call)
......
}
catch (E1) {......}
catch (E2) {......}
}
[230]
void EGC()
{
if (...) { //예외 상황 발생
throw E1(...);
}
else { //정상 로직
......
}
}
비트교육센터
예외 처리 방식 (2)
예외 처리 관련 키워드
– try
•
•
예외 발생에 대해 검사를 수행할 범위를 설정한다.
범위(블록)는 try 키워드로 시작하고 바로 뒤이어 나오는 한 쌍의 중괄호({})
로 설정된다.
– catch
• 발생한 예외를 포착하고 처리하는 블럭을 선언할 때 사용한다.
• catch 키워드로 시작하고 중괄호로 이루어지는 블록내부에 처리 내용을 코딩
한다.
• catch 블록은 try블록의 바로 뒤에 위치시킨다.
– throw
• 특정 예외 상황이 발생하였음을 알린다.
• throw 키워드로 시작하며, 바로 뒤에 그 예외의 특징을 나타내는 문자열이나
객체와 같은 하나의 값을 반환한다.
• 이 값의 타입으로 여러 개의 catch 블록 중 실제 실행될 블록을 찾아낸다.
[231]
비트교육센터
예외 처리 방식 (3)
try 블록 설정
– 하나의 함수 내에 둘 이상의 try블록이 설정될 수 있다.
– 하나의 try 블록 내부에 다른 try블록이 내포될 수 있다.
– try 블록도 명시적인 블록이므로 해당 블록 내에서 선언된 변수들은 그 블록이 끝나
면 사용할 수 없다.
catch 블록 설정
– catch 블록 설정 시 해당 블록에서 처리할 예외의 타입를 명시한다.
– 명확한 타입 대신 생략 기호(...)를 사용하면 모든 종류의 예외를 포착할 수 있다.
– 하나의 try블록 뒤에 둘 이상의 catch블록들이 올 수 있으며, 앞에서부터 차례대로
예외의 타입이 맞는지 검사 하게 된다.
– 경우에 따라 catch블록에서 해당 예외에 대한 처리를 직접 하지 않고 다시 throw할
수 있다.
(예) catch (int num) {
if (num ==0) cout << “This Number is Zero” << endl;
else throw;
}
[232]
비트교육센터
예외 명세 함수
예외 명세(exception specification)
– 예외 명세를 함으로써, 해당 함수가 발생시킬 수 있는 예외들의 종류를 지정할 수
있다.
– 인터페이스 사용자들에게 어떤 예외가 발생되는 지 알려주기 위한 것이다.
void f (int a) throw (x1, x2) {......}
double g (double n, double m) throw ( ){......}
- f() 함수에서는 x1, x2 타입의 예외나 혹은 그로부터 파생된객체
타입의 예외가 발생할 수 있다.
- g() 함수에서는 예외를 발생시키지 않는다.
[233]
비트교육센터
스택 풀기(Stack Unwinding)
스택 풀기
– 발생한 예외에 대하여 처리할 catch 블록이 없는 경우, 자동으로 상위 함수로 예외
객체를 전달한다.
– 만약 main()함수까지 전달되었을 때에도 처리할 catch() 블록이 없으면 프로그램이
종료된다.
step7.
throw
f1()
step6.
throw
f2()
step1.
f2() call
step8.
E1 예외 처리
step5.
throw
f3()
step2.
f3() call
[234]
f4()
step3.
f4() call
step4.
E1 예외 발생 :
E1처리 catch 블록이
f4(), f3(), f2()에는 없고,
f1()에만 있다.
비트교육센터
예외와 클래스 (1)
다른 클래스의 멤버로 내포되는 예외 클래스 정의
– 어떤 함수들이 예외를 발생시킨다면, 발생되는 예외의 타입으로 사용할 클래스를
public 멤버로 정의하는 것이 좋다.
class Vector{
int size;
public:
class ERange {......}; //out of Range Exception
class ESize {......}; //bad Size Exception
//......
};
void f()
{
try { use_vector(); }
catch (Vector::ERange) {......}
catch (Vector::ESize) {......}
//......
}
[235]
비트교육센터
[236]
비트교육센터
예외와 클래스 (2)
전역으로 예외 클래스 정의
– 특정 개체와 관련되어서만 발생하는 예외가 아니면 전역으로 정의하여도 좋다.
class ERange {......}; //out of Range Exception
class ESize {......}; //bad Size Exception
class Vector{
int size;
public:
//......
};
void f()
{
try { use_vector(); }
catch (ERange) {......}
catch (ESize) {......}
}
[237]
비트교육센터
예외의 상속
예외 클래스의 상속
1. 어떤 클래스가 public 멤버로 예외 클래스를 가지고 있다면, 그것을 기본으로 하여
파생되는 클래스들은 그 예외 클래스들을 상속한다.
2. 기존에 정의되어 있는 예외 클래스들로부터 새로운 예외 클래스를 파생시킬 수 있
다.
3. 동일한 범주의 예외 상황들을 클래스 계층 구조로 표현함으로써 관리가 용이해진다.
class MathErr {......};
class Overflow : public MathErr {......};
class Underflow : public MathErr {......};
class ZeroDivide : public MathErr {......};
[238]
비트교육센터
[239]
비트교육센터
[240]
비트교육센터
예외 주의 사항
예외 사용시 주의 사항
– 예외 명세를 사용하는 함수에서 예외가 발생하면, 그 예외는 명세 목록에 있는 데이
터 타입 중에 하나여야 한다. 그렇지 않으면 Unexpected Exception이 발생하고 프
로그램이 중단된다.
– 발생된 예외에 대하여 catch블록에서 포착되어 처리되어야 한다. 만약 해당하는
catch블록이 없다면 Uncaught Exception이 발생하고 프로그램이 중단된다.
– 예외를 많이 사용하면 프로그램의 크기가 커지고, 실행 속도가 떨어질 수 있다.
– 예외가 발생하는 경우, 사용 중이던 리소스에 대한 반환이 정확하게 이루어지도록
catch 블록을 신중하게 구성해야 한다.
[241]
비트교육센터
exception 클래스
exception 클래스
– exception 헤더 파일에 선언되어 있다.
– 다른 예외 클래스들의 기본 클래스로 사용된다.
– what() 이라는 가상(virtual function) 함수가 주어진다. 이 함수를 이용하여 반환할
문자열을 지정해 줄 수 있다.
[242]
비트교육센터
[243]
비트교육센터
[244]
비트교육센터
[245]
비트교육센터
[246]
비트교육센터
[247]
비트교육센터
Chapter
09
스트림(Stream)
스트림
스트림이란?
– 입력과 출력을 바이트들의 흐름
– 프로그램과 입력장치, 혹은 프로그램과 출력장치 사이의 매개자 역할을 한다.
– 표준화된 인터페이스를 제공함으로써, 입력 및 출력 장치의 종류에 상관없이 동일
한 처리 방법을 제공한다.
Keyboard
Camera
File
& etc.
Program
입력 스트림
출력 스트림
Monitor
File
Printer
& etc.
임의 타입의 객체들
char*
Person
String
Complex
int
[249]
비트교육센터
스트림 클래스 계층구조
ios
istream
fstreambase
ostream
iostream
ifstream
ofstream
fstream
[250]
비트교육센터
output stream : cout (1)
cout(ostream) 객체의 기본 출력 연산자 (멤버함수)
– 모든 Built-in 타입에 대해 “<<“ 연산자 오버로딩 되어 있다.
class ostream : public virtual ios {
public:
// …
ostream& operator<<(const char*); // strings
ostream& operator<<(char);
ostream& operator<<(int);
ostream& operator<<(long);
ostream& operator<<(float);
ostream& operator<<(double);
ostream& operator<<(const void*); // pointers
//…
};
[251]
비트교육센터
output stream : cout (2)
cout 객체의 다른 출력 함수(멤버함수)
– put() : 단일 문자 출력 함수이며, 연속적인 호출이 가능하다.
ostream& put (char);
– write() : 전체 문자열을 출력한다. 출력할 문자열과 출력 길이를 인자로 전달하며,
널 문자에 상관없이 무조건 해당 길이만큼의 문자열을 출력한다.
basic_ostream<charT,traits>& write(const char_type*s, streamsize n);
[252]
비트교육센터
output stream : cout (3)
출력 형식 지정
– 출력 시 필드 폭을 지정할 수 있다
: width() 멤버 함수 -> 바로 다음에 출력되는 항목에만 영향을 주고, 원래 기본
설정으로 되돌아간다.
– 정수 출력 시에 16, 10, 8진법을 선택할 수 있다
: hex(), dec(), oct()
– 부동 소수점수의 출력 시에 정밀도를 설정할 수 있다.
: precision() -> 컴파일러 버전에 따라 precision(n)의 인자로 전달되는 수를 전
체 자릿수로 해석할 수도 있고, 소수점 이하의 자릿수로 해석할 수도 있다.
[253]
비트교육센터
[254]
비트교육센터
output stream : cout (4)
출력 형태 플래그 설정
– setf()와 flags()에 플래그를 사용하여 출력 형태를 지정할 수 있다.
const int my_ioflag = ios::left|ios::oct|ios::showpoint|ios::fixed;
old_flag = cout.flags(my_ioflag); //이전 플래그 값을 저장함
cout.setf(ios::showpos);
//새로운 플래그를 지정 : explicit '+' for positive int
[255]
비트교육센터
output stream : cout (5)
출력 형태 플래그 설정(cont’d)
– 정수 출력 시 진법을 선택하는 플래그
cout.setf ( ios::oct, ios::basefield );
cout.setf ( ios::dec, ios::basefield );
cout.setf ( ios::hex, ios::basefield );
// octal
// decimal
// hexadecimal
– 정렬방법(right, left, internal)을 설정하는 플래그
cout.setf ( ios::left, ios::adjustfield );
// left
cout.setf ( ios::right, ios::adjustfield );
// right
cout.setf ( ios::internal, ios::adjustfield ); // internal
[256]
비트교육센터
output stream : cout (6)
출력 형태 플래그 설정(cont’d)
– 부동 소수점 출력 형태 설정 플래그
cout.setf ( ios::scientific, ios::floatfield );
cout.setf ( ios::fixed, ios:: floatfield );
cout.setf (0, ios:: floatfield );
[257]
// scientific number
// fixed point number
// reset to default
비트교육센터
[258]
비트교육센터
output stream : cout (7)
출력 버퍼 비우기
–
출력 작업 시에 사용하는 버퍼는 다음과 같은 경우에 비우기 작업이 일어난다.
1. 버퍼가 꽉 차게 되면 비운다.
2. 개행 문자를 보내면 버퍼가 비워진다.
3. 입력이 발생했을 때, 입력에 앞서 버퍼가 비워진다.
4. tie() 함수 실행 시 버퍼가 비워진다.
5. 명시적으로 직접 호출하여 버퍼를 비울 수 있다. : flush(), endl()
[259]
비트교육센터
input stream : cin (1)
cin 객체의 기본 입력 연산자 (멤버함수)
– 모든 Built-in 타입에 대해 “>>“ 연산자 오버로딩 되어 있다.
class istream : public virtual ios {
// ...
public:
istream& operator>>(char*);
// string
istream& operator>>(char&); // character
istream& operator>>(short&);
istream& operator>>(int&);
istream& operator>>(long&);
istream& operator>>(float&);
istream& operator>>(double&);
istream& get(char& c);
istream& get(char* p, int n, char ='\n');
istream& putback(char& c);
// ...
};
[260]
비트교육센터
input stream : cin (2)
스트림 상태를 나타내는 값
class ios {
// ...
public:
enum io_state {
goodbit =0,
eofbit =1,
failbit =2,
badbit =4,
};
int eof() const;
int fail() const;
int bad() const;
int good() const;
// end of file seen
// next operation will fail
// stream corrupted
// next operation might succeed};
[261]
비트교육센터
input stream : cin (3)
cin(istream) 객체의 다른 입력 함수(멤버함수)
– get() : 단일 문자 입력 함수이며, 연속적인 호출이 가능하다. 여백을 건너뛰지 않고
데이터형 변환도 수행하지 않으며, 문자를 받아들인다.
istream& get (char& ch) : 입력 문자를 전달인자에 대입한다.
get (void) : 입력 문자를 정수형, 보통 int형으로 변환하여 반환한다.
– getline() : 문자열 입력 함수. 1번째 전달인자는 입력 문자열을 저장할 공간이며,
2번째 전달인자는 읽어들일 최대 문자수, 3번째 전달인자는 종료문자로, 이
종료문자를 만나면 지정된 개수의 문자를 읽기 전이라도 입력을 멈춘다.
istream& getline (char*, int, char = ‘\n’);
istream& get (char*, int, char = ‘\n’);
– ignore() : 문자열을 읽고 나서, 읽은 문자열을 버리는 함수
istream& ignore (int=1, int=EOF);
[262]
비트교육센터
input stream : cin (4)
cin(istream) 객체의 다른 입력 함수(멤버함수) (cont’d)
– read() : 주어진 수의 바이트들을 읽어서 지정된 위치에 저장하며, 입력에 널문자를
붙이지 않는다. 보통 키보드 입출력보다는 write()과 함께 파일 입출력에 사
용된다.
– peek() : 입력 스트림으로부터 추출하는 일 없이 입력에 있는 다음 문자를 반환한다.
– gcount() : 마지막 추출 멤버함수가 읽은 문자 수를 반환한다.
– putback() : 어떤 문자를 입력 스트림에 다시 넣는다. (조금 전에 읽은 문자가 아닌
문자도 입력 스트림에 넣을 수 있다.)
[263]
비트교육센터
파일 I/O (1)
파일 입출력의 기본 단계
1. 필요한 헤더 파일을 포함한다.
: fstream.h or fstream, iostream.h or iostream
2. 스트림을 관리하기 위해 객체를 생성한다.
: ofstream 또는 ifstream 타입의 객체
3. 생성된 객체를 하나의 파일에 연결시킨다.
: open() 함수
: 경우에 따라서는 객체 생성과 동시에 파일에 연결시킬 수도 있다.
4. 표준 입출력을 사용하는 것과 동일한 방법으로 그 객체를 사용한다.
5. 사용이 끝난 객체에 대해 파일과의 연결을 닫는다.
: close() 함수
[264]
비트교육센터
파일 I/O (2)
파일 열기와 닫기
– open() : 파일 입출력을 위해 파일을 열어주는 멤버 함수로, 파일의 이름과 열기 모드,
접근 모드의 세가지 정보를 인자로 받는다.
void open (const char* filename, int mode, int access);
: 파일 열기 모드
열기 모드 상수
내용
ios::app
파일의 끝에 추가한다.
ios::ate
파일이 열릴 때, 파일의 끝을 찾는다.
ios::binary
이진 형식으로 파일을 연다.
ios::nocreate
파일이 존재하지 않을 경우 열기에 실패한다.
ios::noreplace
파일이 이미 존재하는 경우에 열기에 실패한다.
ios::trunc
파일이 존재하는 경우에 그 파일의 크기를 0로 만든다.
[265]
비트교육센터
파일 I/O (3)
파일 열기와 닫기 (cont’d)
– is_open() : open()의 실행이 실패하였을 경우 false를 반환하는 멤버 함수
– close() : 열린 파일을 닫는 멤버 함수
– eof() : 파일의 끝에 도달했는지 검사하여, 파일 끝이라면 0이 아닌 값을 반환하고,
파일 끝이 아니라면 0을 반환한다.
[266]
비트교육센터
파일 I/O (4)
텍스트 파일(text file)의 입출력
– 기본적으로 파일 입력과 출력에 사용되는 멤버 함수들은 표준 입출력 함수들과 같
은 함수들이다.
istream& get (char& ch);
ostream& put (char& ch);
//파일에서 단일 문자 입력
//파일로 단일 문자 출력
istream& get (char* buf, int num, char delim=‘\n’);
//파일로부터 최대 num개의 문자를 ‘\n’이 입력되기 전까지 buf로 입력
istream& getline (char* buf, int num, char delim=‘\n’);
//파일로부터 최대 num개의 문자를 ‘\n’이 입력되기 전까지 buf로 입력
int peek();
//파일의 다음 문자를 추출하지 않고 엿보기
istream& putback (char c); //파일로부터 읽어들인 마지막 문자 파일로 되돌리기
ostream& flush(); // 출력 버퍼가 가득 차기 전에 버터의 내용 파일로 출력
[267]
비트교육센터
파일 I/O (5)
이진 파일(binary file)의 입출력
– 이진 파일 : 데이터가 컴퓨터의 내부적인 표현 그대로 저장되는 파일
– 숫자를 저장하는 데 있어서 반올림 등의 변화 없이 데이터가 그대로 저장되므로 더
정확하고, 처리 속도가 빠르다.
– 2진 파일의 데이터를 다른 시스템으로 옮기는 것은 표현 방법의 차이로 인해 문제가
발생할 수 있다.
– 파일을 열 때, 이진 모드(ios_base::binary)로 열어야 한다.
istream& read (unsigned char* buf, int num);
//num크기 만큼의 이진 데이터 블록을 파일로부터 buf로 입력
ostream& write (const unsigned char* buf, int num);
//buf에 있는 num크기 만큼의 이진 데이터를 파일로 출력
[268]
비트교육센터
[269]
비트교육센터
파일 I/O (6)
임의 접근 파일(random file)의 입출력
– 임의 접근 파일 : 파일 데이터에 처음부터 차례로 접근하는 것이 아니라, 원하는 곳
으로 직접 이동하여 처리하는 파일
– 이진 파일과 마찬가지로 ios::binary로 접근해야 한다.
– 원하는 위치로 이동하여 데이터를 입력받거나 출력하기 위해서 seekg()과 seekp()
함수를 사용한다.
istream& seekg (streampos offset, seek_dir origin);
ostream& seekp (streaampos offset, seek_dir origin);
//파일의 현재 입력 위치를 origin의 위치에서 offset만큼 떨어진 위치로 이동
streampos tellg();
streampos tellp();
//파일 포인터의 현재 위치 제공
[270]
비트교육센터
[271]
비트교육센터
Chapter
10
이름공간(Namespace)
이름 공간
Namespace B
Namespace A
c12
v1
c1
c3
c2
c8
v2
v1
func1
c11
func7
c13
c14
c5
c4
v5
v6
c6
c7
func2
c9
c15
c8
func4
func3
c16
c10
[273]
func3
c18
c19
func5
c10
비트교육센터
이름 공간의 선언
이름 공간의 선언과 정의
–
–
–
–
namespace 라는 키워드를 사용하여 새로운 이름 공간을 생성한다.
이름 공간은 전역 위치에 혹은 다른 이름 공간에 선언할 수 있다.
블록 내부에는 이름 공간을 선언할 수 없다.
변수, 객체, 함수의 이름으로 동일한 이름이 서로 다른 이름 공간에 정의될 수 있다.
이름 공간의 기본 구성
namespace namespace-name
{
// declaration and definitions
}
또는
namespace namespace-name
{
// declarations
}
namespace-name::member-name
// definition
[274]
비트교육센터
이름 공간 내부 객체 사용 (1)
이름 공간 내부 객체 사용
– 이름 공간 안에 선언되어 있는 객체나 변수, 함수에 접근하기 위해서는 범위 지정
연산자(::)를 사용하여 소속을 밝힌다.
namespace Bank
{
class Account
{
private:
char CustomerName[20];
char AccountNo[20];
double balance;
public:
Bank::Account::Account(char*, char*, double);
void print();
};
double todaycount = 10;
double totalbalance = 100000;
};
[275]
비트교육센터
이름 공간 내부 객체 사용 (2)
using 선언
– 이름 공간 안에 소속된 객체들에 대해 접근할 때마다 언제나 범위 지정 연산자를 사
용하여 소속(이름공간)을 밝히는 것은 귀찮은 일.
– using 선언을 이용하여 쉽고 편하게 접근할 수 있다.
using Bank::Account;
//프로그램의 전역에 위의 코드를 넣으면, 프로그램 전역에서
//Bank::Account라고 소속을 밝히지 않고 간단히 Account 로 사용할 수 있다.
//특정 함수 내에 위의 코드를 넣으면, 그 함수 내에서만 Account로 간단히
//부를 수 있다.
[276]
비트교육센터
이름 공간 내부 객체 사용 (3)
using namespace 지시자
– 이름 공간 내부의 객체 하나에 대해서만 소속을 미리 밝혀주는 using선언과 달리
using 지시자는 하나의 이름 공간 내부의 모든 변수, 객체, 함수에 대해 범위 지정
연산자 없이 사용할 수 있게 한다.
– 이 지시자를 이용하게 되면 내부 객체나 함수 등을 사용하기에는 편리하겠지만 이
름 충돌이 발생할 확률이 높아지게 되므로 권장하지 않는다.
– 이름 공간 내부에서 필요한 것들만을 선택하여 using 선언을 하는 것을 권장한다.
using namespace Bank;
//프로그램의 전역에 위의 코드를 넣으면, 프로그램 전역에서
//Bank 이름 공간에 관련된 모든 변수나 객체, 함수에 그 이름 만으로 간편하게
//사용할 수 있다.
[277]
비트교육센터
이름 공간 내부 객체 사용 (4)
이름 공간의 중첩
– 이름 공간의 내부에 다시 다른 이름의 공간을 중첩할 수 있다.
– 내부에 중첩된 이름 공간에 선언된 이름(함수, 변수 등)에 접근할 때에는 외부의 이
름 공간에 대한 소속도 함께 밝혀야 한다.
namespace Bank
{
class Account
{ ...... };
namespace Status
{
double todaycount = 10;
double totalbalance = 100000;
;}
};
Bank::Status::todaycount = 0; //계층적으로 이름 공간을 밝힌다.
Bank::Status::totalbalance = 0;
[278]
비트교육센터
이름 공간 내부 객체 사용 (5)
이름이 지정되지 않은 이름 공간
–
–
–
–
이름이 없는 이름
이름 없는 공간에
이름이 없으므로,
보통 내부 링크를
많다.
namespace
{
int a;
void f() { …. }
int g() { …. }
}
공간을 선언할 수 있다.
선언된 멤버들은 항상 자유롭게 접근 가능하다.
using선언이나 using namespace 지시는 할 수 없다.
가지는 정적 변수(static 변수) 대신 이 기능을 이용하는 경우가
자동인식
[279]
namespace $$$
{
int a;
void f() { …. }
int g() { …. }
}
using namespace $$$;
비트교육센터
이름 공간 내부 객체 사용 (6)
함수 오버로딩(function overloading)
– 서로 다른 이름 공간에 정의된 동일한 이름의 함수가 서로 다른 전달 인자를 가지면
이들에게는 함수 오버로딩의 규칙이 적용된다.
namespace A { void f (int); }
namespace B { void f (char); }
using namespace A;
using namespace B;
void g()
{
f(‘a’); //calls the f() from B
}
[280]
비트교육센터
이름 공간 내부 객체 사용 (7)
이름 공간의 다중 정의
– 이름 공간은 여러 번 정의하여 멤버들을 추가할 수 있다.
namespace A{
int f();
}
namespace A{
int g();
}
//now A has member f()
//now A has two members, f() and g()
[281]
비트교육센터
이름 공간 내부 객체 사용 (8)
using 선언과 using namespace 지시자 사용시 주의할 점
– 이름 공간과 전역 공간, 혹은 지역 공간이 같은 이름의 객체를 정의하고 있는 경우,
using 선언을 사용하여 이름 공간의 이름을 불러오려고 하면 이름 충돌로 인한 에러
가 발생한다.
– using namespace 지시자를 사용하여 그 이름 공간에 있는 이름을 선언 영역으로
불러오면, 그 이름의 지역 버전이 우선순위가 높아진다.
int main(void)
{
int todaycount = 99; //같은 이름의 지역변수
using Bank::todaycount;
//Error~!! : 이름충돌
Account myacc("Hong","134-28-927",1000);
myacc.print();
cout << "Today Count : " << todaycount << endl;
return 0;
}
[282]
비트교육센터
표준 이름 공간 (1)
특징 : 이전 표준 라이브러리들과 템플릿 라이브러리들을 표준 이름 공간에 통합
하여 관리함.
C 라이브러리 관련 파일들
– cassert, cctype, cerrno, cfloat, climits, clocale, cmath, csetjmp, csignal,
cstdarg, cstddef, cstdio, cstdlib, cstring, ctime, cwchar, cwctype
Old C++ 라이브러리 관련 파일들
– exception, complex, fstream, iomanip, ios, iosfwd, iostream, istream, limits,
locale, ostream, sstream, stdexcept, streambuf, strstream, valarray
C++ 표준 템플릿 라이브러리들
– algorithm, deque, functional, iterator, list, map, memory, numeric, queue,
set, stack, utility, vector
[283]
비트교육센터
표준 이름 공간 (2)
// <iostream>
namespace std
{
extern istream cin;
extern ostream cout;
extern ostream cerr;
extern ostream clog;
// …
};
// <cstdlib>
namespace std
{
#include <stdlib.h>
//...
};
// <exception>
namespace std
{
class exception;
class bad_exception;
typedef void (*terminate_handler)();
typedef void (*unexpected_handler)();
terminate_handler
set_terminate(terminate_handler ph) throw();
unexpected_handler
set_unexpected(unexpected_handler ph) throw();
void terminate();
void unexpected();
bool uncaught_exception();
};
[284]
비트교육센터