Chapter 6 구조체.

Slides:



Advertisements
Similar presentations
명품 C++ 프로그래밍 3장. 클래스와 객체.
Advertisements

슬라이드 1~21까지는 각자 복습! 슬라이드 22부터는 수업시간에 복습
Power C++ 제6장 포인터와 문자열.
C++ Espresso 제3장 배열과 포인터.
C++ Espresso 제3장 배열과 포인터.
C++ Espresso 제1장 기초 사항.
쉽게 풀어쓴 C언어 Express 제11장 포인터 C Express.
C++ Espresso 제2장 제어문과 함수.
강좌명 : C++프로그래밍 (C++ Programming)
C 프로그래밍.
제6장 객체배열과 벡터 객체 배열을 이해한다. 벡터(vector) 클래스를 사용할 수 있다.
8. 객체와 클래스 (기본).
C 6장. 함수 #include <stdio.h> int main(void) { int num;
C 10장. 함수의 활용 #include <stdio.h> int main(void) { int num;
C 11장. 포인터의 활용 #include <stdio.h> int main(void) { int num;
쉽게 풀어쓴 C언어 Express 제17장 동적 메모리와 연결 리스트 C Express.
C++ Espresso 제9장 다형성.
쉽게 풀어쓴 C언어 Express 제4장 변수와 자료형 C Express.
C언어: 배열 (Arrays).
6장. printf와 scanf 함수에 대한 고찰
10장 템플릿과 표준 템플릿 라이브러리(STL)
윤성우의 열혈 C 프로그래밍 윤성우 저 열혈강의 C 프로그래밍 개정판 Chapter 14. 포인터와 함수에 대한 이해.
자료 구조: Chapter 3 (2)구조체, 포인터
C++ Espresso 제6장 생성자와 소멸자.
10장 메모리 관리.
쉽게 풀어쓴 C언어 Express 제17장 동적 메모리와 연결 리스트 C Express.
쉽게 풀어쓴 C언어 Express 제17장 동적메모리와 연결리스트 C Express.
동적메모리와 연결리스트 컴퓨터시뮬레이션학과 2016년 봄학기 담당교수 : 이형원 E304호,
3장. 포인터, 배열, 구조체 포인터, 배열, 구조체 학습목표 기본적 데이터 타입
C 7장. 배열과 문자열 #include <stdio.h> int main(void) { int num;
명품 C++ 7장 프렌드와 연산자 중복.
18장. 헤더 파일과 구현 파일 01_ 헤더 파일과 구현 파일의 사용.
Chapter 05. 클래스 완성. chapter 05. 클래스 완성 01. 복사 생성자 복사 생성(Copy Construction) 생성될 때 자신과 같은 타입의 객체를 변수로 받아, 이 객체와 같은 값을 갖는 새로운 객체를 생성하는 것 명시적인 생성 과정뿐만.
C++ Programming: Sample Programs
10장 포인터와 문자열 포인터 기본 배열과 포인터 매개변수 전달방법 포인터와 문자열.
C ++ 프로그래밍 시작.
정적 멤버 변수/정적 멤버 함수 - friend 함수/클래스 template
C++ 개요 객체지향 윈도우즈 프로그래밍 한국성서대학교 유일선
프로그래밍2 및 실습 C언어 기반의 C++ 2.
스택(Stack) 김진수
C++ 프로그래밍 년 2학기 전자정보공학대학 컴퓨터공학부.
C 4장. 연산자 #include <stdio.h> int main(void) { int num;
Chapter 3 클래스. 최호성.
제5장 생성자와 접근제어 객체 지향 기법을 이해한다. 클래스를 작성할 수 있다. 클래스에서 객체를 생성할 수 있다.
가상함수와 추상 클래스.
11장. 1차원 배열 IT응용시스템공학과 김 형 진 교수.
Chapter 1 C와는 다른 C++. 최호성.
제2장 제어구조와 배열 if-else 문에 대하여 학습한다. 중첩 if-else 문에 대하여 학습한다.
컴퓨터 프로그래밍 기초 - 4th : 수식과 연산자 -
제 12장. 사용자 정의형으로서의 클래스 학기 프로그래밍언어및실습 (C++).
4. 고급변수 사용 : 포인터와 관련하여 메모리 바라보기
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
게임프로그래밍 I - 1차원 배열 - 공주대학교 게임디자인학과 박 찬 교수 2011년 4월 25일.
멤버 함수인 operator+()가 실행, 또는 전역 함수인 operator+()가 실행 Point p3 = p1+p2; 에서
제8장 포인터와 동적객체 생성 포인터의 개념을 이해한다. 포인터와 관련된 연산을 이해한다.
C89(C++03) 프로그래밍 (Part 2) 7 배열 8 변수 범위 9 포인터 10 유도 자료형.
제 11장. 템플릿과 STL 학기 프로그래밍언어및실습 (C++).
03. 메모리 관리 C++ 프로그램에서 다룰 수 있는 메모리의 종류
10장 템플릿과 표준 템플릿 라이브러리(STL)
반복문의 기능 반복문 반복문 특정 영역을 특정 조건이 만족하는 동안에 반복 실행하기 위한 문장 while문
9장. C 언어의 핵심! 함수. 9장. C 언어의 핵심! 함수 9-1 함수의 정의와 선언 main 함수 다시 보기 : 함수의 기본 형태 { } 그림 9-1.
실습과제 1번 /* 1. 멤버 변수로 반경 radius를 갖고, 그 값을 모니터에 출력하는
17장. 포인터의 포인터.
C 4장. 연산자 #include <stdio.h> int main(void) { int num;
C 프로그래밍은 매우 도전적인 작업이다. 도전의 이면에 철저한 준비와 체계적인 노력
C++ 언어의 특징
윤성우의 열혈 C++ 프로그래밍 윤성우 저 열혈강의 C++ 프로그래밍 개정판 Chapter 02. C언어 기반의 C++ 2.
배열, 포인터, 함수 Review & 과제 1, 2.
프로그래밍 기법 최적화 프로그래밍.
Presentation transcript:

Chapter 6 구조체

구조체 struct Point { int x; // x좌표 int y; // y좌표 }; struct Customer { char name[10]; // 이름 char phone[20]; // 전화번호 char address[50]; // 주소 int age; // 나이 int sex; // 성별 float height; // 키 float weight; // 몸무게 };

구조체 변수의 선언 #include <stdio.h> struct Point { int x; // x좌표 int y; // y좌표 }; int main(void) struct Point pt; printf("Point의 크기: %d\n", sizeof(pt)); return 0; }

구조체 변수의 초기화 struct Point { int x; // x좌표 int y; // y좌표 }; int main(void) struct Point pt1 = {10, 20}, pt2 = {50, 60}; ... return 0; }

구조체의 사용 #include <stdio.h> struct Point { int x; // x좌표 int y; // y좌표 }; int main(void) struct Point pt1 = {10, 20}, pt2 = {50, 60}; printf("첫째 점의 좌표: (%d, %d)\n", pt1.x, pt1.y); printf("둘째 점의 좌표: (%d, %d)\n", pt2.x, pt2.y); return 0; }

구조체의 배열 #include <stdio.h> struct Point { int x; // x좌표 int y; // y좌표 }; int main(void) int i; struct Point pt[3] = {{10, 20}, {30, 40}, {50, 60}}; for(i=0 ; i<3 ; i++) printf("%d번째 점의 좌표: (%d, %d)\n", i+1, pt[i].x, pt[i].y); } return 0;

구조체의 포인터 printf("첫번째 구조체 값: (%d, %d)\n\n", (*ptr).x, (*ptr).y); #include <stdio.h> struct Point { int x; // x좌표 int y; // y좌표 }; int main(void) int i; struct Point pt[3] = {{10, 20}, {30, 40}, {50, 60}}; struct Point *ptr = pt; for(i=0 ; i<3 ; i++) printf("%d번째 구조체 값: (%d, %d)\n", i+1, ptr[i].x, ptr[i].y); } printf("첫번째 구조체 값: (%d, %d)\n\n", (*ptr).x, (*ptr).y); printf("첫번째 구조체 값: (%d, %d)\n\n", ptr->x, ptr->y); return 0;

구조체 멤버변수 #include <stdio.h> struct Point { int x; // x좌표 int y; // y좌표 }; struct Circle struct Point center; // 중심의 좌표 double radius; // 반지름 int main(void) struct Circle c1 = {{10, 10}, 5.0}; printf("원의 중심 좌표: (%d, %d)\n", c1.center.x, c1.center.y); printf("원의 반지름: %0.2f\n", c1.radius); return 0; }

구조체의 포인터 멤버변수 struct NoGood { NoGood member; // 에러 }; struct List { int member; struct List *next; };

구조체 활용 1/3 #include <stdio.h> #include <malloc.h> #include <string.h> #define MAX_NAME 50 struct Item { char name[MAX_NAME]; // 품명 int price; // 단가 int num; // 수량 };

구조체 활용 2/3 int main(void) { int i; int count, sum=0, total; // 항목개수, 합계, 총액 struct Item *item = NULL; // 항목 printf("항목의 개수를 입력하세요: "); scanf("%d", &count); // 항목개수 입력 item = malloc(count * sizeof(item)); // 메모리 할당 for(i=0 ; i<count ; i++) printf("\n품명: "); fgets(item[i].name, MAX_NAME-1, stdin); // 품명 입력 item[i].name[strlen(item[i].name)-1] = '\0'; // '\n' 제거 printf("단가: "); scanf("%d", &item[i].price); // 단가 입력 printf("수량: "); scanf("%d", &item[i].num); // 수량 입력 } ...

구조체 활용 3/3 ... printf("------------------------------\n"); printf("품명\t단가\t수량\n"); for(i=0 ; i<count ; i++) { printf("%s\t", item[i].name); // 품명 출력 printf("%d\t", item[i].price); // 단가 출력 printf("%d\n", item[i].num); // 수량 출력 sum += (item[i].price * item[i].num); // 합계 계산 } free(item); // 메모리 반납 total = (int)(sum * 1.1); // 부가세 포함금액 printf("합계: %d\n", sum); printf("총액: %d (부가세 10%%포함)\n", total); return 0;

구조체 멤버변수의 정렬 1/2 #include <stdio.h> struct s1 { char c; short s; int i; }; struct s2 int main(void) printf("s1의 크기: %d\n", sizeof(struct s1)); printf("s2의 크기: %d\n", sizeof(struct s2)); return 0; }

구조체 멤버변수의 정렬 2/2 struct s1 struct s2 char c char c 정렬단위 정렬단위 short s int i int i 정렬단위 정렬단위 short s 정렬단위

지역변수 int add(int val1, int val2) { int result; result = val1 + val2; return result; }

전역변수 int global = 0; int main(void) { ... }

정적변수 #include <stdio.h> int Count(void); int main(void) { int i, count; for(i=0 ; i<5 ; i++) count = Count(); printf("Count 함수가 %d번 호출되었습니다.\n", count); } return 0; int Count(void) static int count = 0; count++; return count;

변수의 종류에 따른 사용 범위와 수명 선언 방법 사용 범위 메모리에 존재하는 수명 지역변수 함수 안에서 선언 함수 내 함수가 실행되는 동안 전역변수 함수 밖에서 선언 프로그램 전체 프로그램이 실행되는 동안 정적변수 함수 안/밖에서 static 키워드를 붙여 선언 함수 안에서 선언: 함수 내 함수 밖에서 선언: 파일 내

Chapter 9 C 문법의 확장

변수선언 int main(void) { int result, a=3, b=4; result = a+b; int i; for(i=0 ; i<10 ; i++) result += i; } return 0;

bool 타입 int main(void) { int num = -10; bool isNegative; isNegative = num<0; if(isNegative == true) num = -num; return 0; }

레퍼런스 struct Point { double x, y; }; struct Circle struct Point center; double radius; int main(void) struct Circle cir1; cir1.center.x = 3; double &cx = cir1.center.x; ... return 0; } int &ref; // 컴파일 에러 int &ref = 10; // 컴파일 에러

범위지정 연산자 1/2 namespace Graphics { int value; void Initialize(void) ... } namespace Network int main(void) Graphics::Initialize(); Network::Initialize(); return 0; using namespace Graphics; using Graphics::Initialize;

범위지정 연산자 2/2 int value = 0; // 전역변수 선언 int main(void) { return 0; }

출력 연산자 std::cout << "Hello"; std::cout << std::endl; std::cout << "Hello" << std::endl; int num = 10; std::cout << "num = " << num << std::endl; #include <iostream> using namespace std; int main(void) { int num = 10; cout << "num = " << num << endl; return 0; }

입력 연산자 int num; std::cin >> num;

new/delete 연산자 int *ptrOne = new int; int *ptrTen = new int [10]; delete ptrOne; delete [] ptrTen; cf) int *ptrAlloc = (int*)malloc(sizeof(int)*10);

오버로딩 (Overloading) #include <iostream> using namespace std; int add(int a, int b); double add(double a, double b); int main(void) { int i1=10, i2=20; double d1=0.1, d2=0.2; cout << "i1+i2 = " << add(i1, i2) << endl; cout << "d1+d2 = " << add(d1, d2) << endl; return 0; } int add(int a, int b) return a+b; double add(double a, double b)

오버로딩 주의점 void function(void) { ... } int function(void) // 컴파일 에러 return 0;

디폴트 매개변수 값 #include <iostream> using namespace std; void PrintDate(int year=2000, int month=1, int day=1); int main(void) { PrintDate(); // 2000. 1. 1을 지정 PrintDate(2010); // 2010. 1. 1을 지정 PrintDate(2010, 8); // 2010. 8. 1을 지정 PrintDate(2010, 8, 5); // 2010. 8. 5를 지정 return 0; } void PrintDate(int year, int month, int day) cout << year << "년 " << month << "월 " << day << "일" << endl;

오버로딩된 함수의 디폴트 매개변수 void output(int num=10); void output(void); { cout << num; } void output(void) cout << 20; int main(void) output(); // 컴파일 에러 return 0;

inline 함수 #include <iostream> using namespace std; int add(int a, int b); int main(void) { int i, sum=0; for(i=0 ; i<100000000 ; i++) sum = add(i, sum); } cout << "sum = " << sum << endl; return 0; inline int add(int a, int b) return a+b;

레퍼런스 인자 #include <stdio.h> void swap(int *a, int *b); int main(void) { int a=10, b=20; swap(&a, &b); printf("a=%d\n", a); printf("b=%d\n", b); return 0; } void swap(int *a, int *b) int temp; temp = *a; *a = *b; *b = temp; #include <iostream> using namespace std; void swap(int &a, int &b); int main(void) { int a=10, b=20; swap(a, b); cout << "a=" << a << endl; cout << "b=" << b << endl; return 0; } void swap(int &a, int &b) int temp; temp = a; a = b; b = temp;

Chapter 10 객체지향 프로그래밍

프로그래밍 방식 구조적 프로그래밍 (Structured Programming) 객체지향 프로그래밍 (Object Oriented Programming)

객체의 분할 프레임 윈도우 메뉴 도구모음 주소입력창 뷰 상태표시줄

C와 C++ C C++ 프로그래밍 방식 구조적 프로그래밍 객체지향 프로그래밍 프로그램 분할 방법 기능 객체 구현 단위 함수 클래스 규모 중소형 프로그램 작성에 적합 중대형 프로그램

객체의 특징 캡슐화 다형성 상속성 사물 생물 무생물 동물 식물 어류 조류 포유류 고등어 참치 참새 꿩 개 고양이 원숭이 오동나무 소나무 전나무 활엽수 침엽수 다형성 상속성

Chapter 11 클래스

C 스타일의 데이터 처리 struct Point { int x, y; }; void SetPosition(struct Point *pPoint, int _x, int _y) pPoint->x = _x; pPoint->y = _y; } void Move(struct Point *pPoint, int _x, int _y) pPoint->x += _x; pPoint->y += _y; void Show(const struct Point *pPoint) printf("(%d, %d)\n", pPoint->x, pPoint->y); int main(void) { struct Point p1, p2; SetPosition(&p1, 10, 20); SetPosition(&p2, 50, 60); Move(&p1, 5, 0); Move(&p2, 0, 5); Show(&p1); Show(&p2); return 0; }

C++ 스타일의 데이터 처리 struct Point { int x, y; void SetPosition(int _x, int _y); void Move(int _x, int _y); void Show(void); }; void Point::SetPosition(int _x, int _y) x = _x; y = _y; } void Point::Move(int _x, int _y) x += _x; y += _y; void Point::Show(void) cout << "(" << x << ", " << y << ")" << endl; int main(void) { Point p1, p2; p1.SetPosition(10, 20); p2.SetPosition(50, 60); p1.Move(5, 0); p2.Move(0, 5); p1.Show(); p2.Show(); return 0; }

접근권한 class 클래스 이름 { public: 멤버변수; 멤버함수; private: };

클래스의 선언 class Point { public: int x, y; void SetPosition(int _x, int _y); void Move(int _x, int _y); void Show(void); };

클래스의 정의 void Point::SetPosition(int _x, int _y) { x = _x; y = _y; } void Point::Move(int _x, int _y) x += _x; y += _y; void Point::Show(void) cout << "(" << x << ", " << y << ")" << endl;

클래스의 사용 int main(void) { Point p1, p2; // 점의 좌표를 저장할 변수 선언 p1.SetPosition(10, 20); // p1의 좌표 설정 p2.SetPosition(50, 60); // p2의 좌표 설정 p1.Move(5, 0); // p1의 좌표 이동 p2.Move(0, 5); // p2의 좌표 이동 p1.Show(); // p1의 좌표를 출력 p2.Show(); // p2의 좌표를 출력 return 0; }

클래스의 내부와 외부 클래스의 내부 void Point::SetPosition(int _x, int _y) { x = _x; y = _y; } 클래스의 외부 int main(void) Point p1, p2; // 점의 좌표를 저장할 변수선언 p1.SetPosition(10, 20); // p1의 좌표 설정 ...

접근권한을 설정하는 이유 추상화 안전성

데이터 감추기 class Point { public: void SetPosition(int _x, int _y); void Move(int _x, int _y); void Show(void); private: int x, y; };

멤버함수를 통한 멤버변수 접근 1/2 #include <iostream> using namespace std; int main(void) { int counter = 0; // 카운터를 리셋 counter++; // 버튼을 한번 누름 cout << counter << endl; // 카운터 값을 출력 return 0; }

멤버함수를 통한 멤버변수 접근 2/2 class Counter { public: void Reset(void); void Click(void); int GetCount(void); private: int count; }; void Counter::Reset(void) count = 0; } void Counter::Click(void) count++; int Counter::GetCount(void) return count; #include <iostream> using namespace std; int main(void) { Counter ct; // 카운터 선언 ct.Reset(); // 카운터를 리셋 ct.Click(); // 버튼을 한번 누름 cout << ct.GetCount(); // 카운터 값을 출력 cout << endl; return 0; }

생성자와 소멸자 class Counter { public: Counter(void); // 생성자 void Reset(void); // 카운터를 리셋 void Click(void); // 버튼을 한번 누름 int GetCount(void); // 카운터의 값을 얻음 private: int count; // 변수에는 접근하지 못하게 함 }; Counter::Counter(void) count = 0; // 변수 초기화 cout << "Constuctor" << endl; } Counter::~Counter(void) cout << "Distructor" << endl;

인스턴스의 생성과 소멸 선언 방법 사용 범위 메모리에 존재하는 수명 지역변수 함수 안에서 선언 함수 내 함수가 실행되는 동안 전역변수 함수 밖에서 선언 프로그램 전체 프로그램이 실행되는 동안 정적변수 함수 안/밖에서 static 키워드를 붙여 선언 함수 안에서 선언: 함수 내 함수 밖에서 선언: 파일 내 Counter *pCounter = new Counter; // 메모리 할당 (생성자 호출) ... delete pCounter; // 메모리 반납 (소멸자 호출) Counter *pCounter = new Counter [5]; // 메모리 할당 (생성자 호출) ... delete [] pCounter; // 메모리 반납 (소멸자 호출) // 메모리 할당 (생성자는 호출되지 않음) Counter *pCounter = (Counter *)malloc(sizeof(Counter)); ... free(pCounter) // 메모리 반납 (소멸자는 호출되지 않음)

생성자의 인자 1/4 class Array { public: Array(void); // 기본 생성자 Array(int size); // 크기를 지정하는 생성자 ~Array(void); // 소멸자 bool SetData(int pos, int data); bool GetData(int pos, int &data); private: int *pData; // 데이터를 저장하기 위한 포인터 int maxsize; // 데이터 저장 공간의 크기 };

생성자의 인자 2/4 Array::Array(void) { maxsize = 100; // 크기를 기본 값으로 설정 pData = new int [maxsize]; // 메모리 할당 } Array::Array(int size) maxsize = size; // 크기를 주어진 값으로 설정 Array::~Array(void) delete [] pData; // 메모리 반납

생성자의 인자 3/4 bool Array::SetData(int pos, int data) { if(pos < 0 || pos >= maxsize) // 범위를 벗어난 쓰기는 실패 return false; pData[pos] = data; // 데이터 쓰기 return true; // 성공 } bool Array::GetData(int pos, int &data) if(pos < 0 || pos >= maxsize) // 범위를 벗어난 읽기는 실패 data = pData[pos]; // 데이터 읽기

생성자의 인자 4/4 #include <iostream> using namespace std; int main(void) { Array data(10); // 10개짜리 공간을 확보 int i, val; for(i=0 ; i<=10 ; i++) if(!data.SetData(i, i)) // 데이터 쓰기 cout << "Fail to set data" << endl; if(!data.GetData(i, val)) // 데이터 읽기 cout << "Fail to get data" << endl; else cout << "Data = " << val << endl; } return 0;

복사 생성자 Array::Array(const Array &data) { maxsize = data.maxsize; pData = data.pData; } maxsize = data.maxsize; // 크기를 같게 설정 pData = new int [maxsize]; // 메모리 공간 할당 memcpy(pData, data.pData, maxsize); // 데이터 영역 복사

포함된 클래스의 생성자 호출 1/2 class Container { public: Container(int size); // ... private: Array data; }; Container::Container(int size) : data(size) }

포함된 클래스의 생성자 호출 2/2 class Container { public: Container(int size); // ... private: Array data(10); // 컴파일 에러 }; Container::Container(int size) data(size); // 컴파일 에러 } Array data(size); // 지역변수 선언

파일의 분할 ClassA.cpp ClassA.h ClassB.cpp ClassB.h main.cpp ClassC.cpp ClassC.h

파일 분할의 예 1/3 // Counter.h 파일의 내용 class Counter { public: Counter(void); // 생성자 void Reset(void); // 카운터를 리셋 void Click(void); // 버튼을 한번 누름 int GetCount(void); // 카운터의 값을 얻음 private: int count; // 변수에는 접근하지 못하게 함 };

파일 분할의 예 2/3 // Counter.cpp 파일의 내용 #include "Counter.h" Counter::Counter(void) // 생성자 { count = 0; } void Counter::Reset(void) // 카운터를 리셋 void Counter::Click(void) // 버튼을 한번 누름 count++; int Counter::GetCount(void) // 카운터의 값을 얻음 return count;

파일 분할의 예 3/3 // main.cpp 파일의 내용 #include <iostream> #include "Counter.h" using namespace std; int main(void) { Counter ct; // 카운터 선언 ct.Reset(); // 카운터를 리셋 ct.Click(); // 버튼을 한번 누름 cout << ct.GetCount(); // 카운터 값을 출력 cout << endl; return 0; }

inline 멤버함수 1/2 class Counter { public: Counter(void) void Reset(void) // 묵시적 inline 함수 count=0; } void Click(void) int GetCount(void); private: int count; };

inline 멤버함수 2/2 #include "Counter.h“ Counter::Counter(void) { } inline void Counter::Click(void) // 명시적 inline 멤버함수 count++; int Counter::GetCount(void) return count;

static 멤버 1/3 #define MAX_NAME 20 class Student { public: Student(char *_name, int _age); // 나이와 이름 초기화 ~Student(void); // 소멸자 void Show(void); // 나이와 이름 출력 static int GetCount(void); // 수강생수를 얻음 private: int age; // 나이 char name[MAX_NAME]; // 이름 static int count; // 수강생 수 };

static 멤버 2/3 int Student::count = 0; // static 멤버변수 선언 및 초기화 Student::Student(char *_name, int _age) { strncpy(name, _name, MAX_NAME-1); age = _age; count++; // 인스턴스 개수 증가 } Student::~Student(void) count--; // 인스턴스 개수 감소 void Student::Show(void) cout << name; cout << " (" << age << ")"; cout << endl; int Student::GetCount(void) return count; // 인스턴스 개수 리턴

static 멤버 3/3 #include "Student.h" #include <iostream> using namespace std; int main(void) { Student s1("김옥빈", 22); Student s2("문근영", 19); Student s3("전지현", 27); s1.Show(); s2.Show(); s3.Show(); cout << "수강생 수: " << Student::GetCount() << endl; return 0; }

this 포인터 1/2 "김옥빈" name 22 age 0x1000 this s1 “문근영" 19 0x1100 s2 “전지현" 27 0x1200 s3 int Student::GetCount() { return count; } 3 count 멤버함수/멤버변수 static 멤버함수/멤버변수 클래스의 외부 void Student::Show() cout << name << age; int main() ... ① ② ③ ④ ⑩ ⑦ ⑧ ⑥ ⑤ ⑨

this 포인터 2/2 int main(void) { ... s1.Show(); } int main(void) { ... Student::Show(s1.this); } void Student::Show() { cout << name << age; } void Student::Show(Student *this) { cout << this->name << this->age; }

static 멤버 호출 인스턴스를 통한 호출 s1.GetCount(); 인스턴스를 통하지 않은 호출 Student::GetCount(); 일반 멤버함수에서 Static 멤버함수 호출 void Student::Show(void) { GetCount(); // OK } Static 멤버함수에서 일반 멤버함수 호출 int Student::GetCount(void) { Show(); // 컴파일 에러 return count; }

this 포인터의 활용 Student::Student(char *_name, int _age) { strncpy(name, _name, MAX_NAME-1); age = _age; count++; } Student::Student(char *name, int age) strncpy(this->name, name, MAX_NAME-1); this->age = age;

멤버함수의 포인터 1/3 #define MAX_NAME 20 class Student { public: Student(char *_name, int _age); // 나이와 이름 초기화 ~Student(void); // 소멸자 void Show(void); // 나이와 이름 출력 static int GetCount(void); // 수강생수를 얻음 static int CompareAge(const void *a, const void *b); static int CompareName(const void *a, const void *b); private: int age; // 나이 char name[MAX_NAME]; // 이름 static int count; // 수강생 수 };

멤버함수의 포인터 2/3 int Student::CompareAge(const void *a, const void *b) { Student *pa = (Student *)a; Student *pb = (Student *)b; if(pa->age > pb->age) return 1; else if(pa->age < pb->age) return -1; else return 0; } int Student::CompareName(const void *a, const void *b) return strcmp(pa->name, pb->name);

멤버함수의 포인터 3/3 #include <iostream> #include "student.h" using namespace std; int main(void) { int i; Student talent[] = {Student("김옥빈",22), Student("문근영",19), Student("전지현",27), Student("이영애",37), Student("송혜교",26) }; int count = Student::GetCount(); cout << "나이순:" << endl; qsort(talent, count, sizeof(Student), Student::CompareAge); for(i=0 ; i< count ; i++) talent[i].Show(); cout << endl << "이름순:" << endl; qsort(talent, count, sizeof(Student), Student::CompareName); for(i=0 ; i<count ; i++) return 0; }

const 상수 const double pi = 3.141592; pi = 10.0; // 컴파일 에러

const 포인터 const int *ptr = NULL int num[2]; ptr = num; ptr++;

const 멤버변수 class Person { public: Person(int id); private: const int id; }; Person::Person(int id) : id(id) } int main(void) Person tom(800828), bob(820213); ... return 0;

const 멤버함수 class Person { public: Person(void); Person(int id); int GetId(void) const; private: const int id; }; int Person::GetId(void) const return id; }

Chapter 12 연산자 오버로딩

연산자와 함수 a = b + c; a = Add(b, c); SetData(a, Add(b, c));

연산자 오버로딩 연산자가 수행하는 기능을 함수로 구현 함수로 구현된 기능을 연산자 표현으로 호출

연산자 오버로딩의 제약 연산자의 본래 기능을 바꾸면 안됨 연산자의 우선순위나 결합성 변경 불가 기본 데이터 타입끼리의 연산자 함수 정의 불가 오버로딩이 금지된 연산자 sizeof 멤버 참조 연산자(.) 범위지정 연산자 (::) 조건 선택 연산자 (?:)

기본 클래스 정의 1/2 // Point.h class Point { public: Point(void); Point(int x, int y); void Show(void); private: int x, y; };

기본 클래스 정의 2/2 // Point.cpp #include "Point.h" #include <iostream> using namespace std; Point::Point(void) { x = y = 0; } Point::Point(int x, int y) this->x = x; this->y = y; void Point::Show(void) cout << "(" << x << ", " << y << ")" << endl;

단항연산자 정의 class Point { ... public: Point operator++(void); Point operator++(int); }; Point Point::operator++(void) // 전위형 ++x, ++y; return *this; } Point Point::operator++(int) // 후위형 Point temp = *this; return temp;

단항연산자 호출 #include <iostream> #include "Point.h“ int main(void) { Point p1(0, 0), p2, p3; p2 = ++p1; // 전위형. operator++() 호출 p1.Show(); p2.Show(); p3 = p1++; // 후위형. operator++(int) 호출 p3.Show(); return 0; }

단항연산자 호출 과정 p2 = ++p1; p2 = p1++; p2 = p1.operator++(); p2 = p1.operator++(int); Point Point::operator++() { ++x, ++y; return *this; } Point Point::operator++(int) { Point temp = *this; ++x, ++y; return temp; }

이항연산자 정의 class Point { ... public: Point operator+(Point pt); }; Point Point::operator+(Point pt) Point temp; temp.x = x + pt.x; temp.y = y + pt.y; return temp; }

이항연산자 호출 #include <iostream> #include "Point.h“ int main(void) { Point p1(10, 20), p2(5, 7), p3; p3 = p1 + p2; p3.Show(); return 0; }

이항연산자 호출 과정 a = b + c; a = b.operator+(c); Point Point::operator+(Point pt) { Point temp; temp.x = x + pt.x; temp.y = y + pt.y; return temp; }

? friend 함수의 필요성 Point p1(10, 20), p2; p2 = p1 * 2; Point Point::operator*(int mag) { Point temp; temp.x = x * mag; temp.y = y * mag; return temp; }

friend 연산자 함수 정의 class Point { ... public: Point operator*(int mag); friend Point operator*(int mag, Point pt); }; Point Point::operator*(int mag) Point temp; temp.x = x * mag; temp.y = y * mag; return temp; } Point operator*(int mag, Point pt) temp.x = mag * pt.x; temp.y = mag * pt.y;

friend 연산자 함수 호출 #include <iostream> #include "Point.h“ int main(void) { Point p1(10, 20), p2; p2 = p1 * 2; // 멤버함수 호출 p2.Show(); p2 = 2 * p1; // friend 함수 호출 return 0; }

friend 연산자 함수 호출 과정 a = 2 * b; a = operator*(2, b); Point Point::operator*(int mag, Point pt) { Point temp; temp.x = mag * pt.x; temp.y = mag * pt.y; return temp; }

연산자 함수의 인자 Point Point::operator+(const Point &pt) { Point temp; temp.x = x + pt.x; temp.y = y + pt.y; return temp; } Point Point::operator*(int mag) temp.x = x * mag; temp.y = y * mag;

연산자 함수 상수화 Point Point::operator+(const Point &pt) const { Point temp; temp.x = x + pt.x; temp.y = y + pt.y; return temp; }

연산자 함수의 리턴 타입 Point &Point::operator=(const Point &pt) { x = pt.x; y = pt.y; return *this; } Point Point::operator+(const Point &pt) const Point temp; temp.x = x + pt.x; temp.y = y + pt.y; return temp; bool Point::operator==(const Point &pt) const return (x == pt.x && y == pt.y); return Point(x + pt.x, y + pt.y);

연산자 함수의 리턴값 상수화 Point &Point::operator++(void) { ++x, ++y; return *this; } const Point Point::operator++(int) Point temp = *this; ++*this; return temp;

대입연산자 1/2 class Point { public: ... Point &operator=(const Point &pt); Point &operator*=(int mag); Point &operator/=(int div); };

대입연산자 1/2 Point &Point::operator=(const Point &pt) { x = pt.x; y = pt.y; return *this; } Point &Point::operator+=(const Point &pt) x += pt.x; y += pt.y; Point &Point::operator-=(const Point &pt) x -= pt.x; y -= pt.y; Point &Point::operator*=(int mag) x *= mag; y *= mag; Point &Point::operator/=(int div) x /= div; y /= div;

산술연산자 1/2 class Point { public: ... Point operator+(const Point &pt) const; Point operator-(const Point &pt) const; Point operator*(int mag) const; Point operator/(int div) const; friend Point operator*(int mag, const Point &pt); friend Point operator/(int div, const Point &pt); };

산술연산자 1/2 Point Point::operator+(const Point &pt) const { return Point(x + pt.x, y + pt.y); } Point Point::operator-(const Point &pt) const return Point(x - pt.x, y - pt.y); Point Point::operator*(int mag) const return Point(x * mag, y * mag); Point Point::operator/(int div) const return Point(x / div, y / div); Point operator*(int mag, const Point &pt) return Point(pt.x * mag, pt.y * mag); Point operator/(int div, const Point &pt) return Point(pt.x / div, pt.y / div);

관계연산자 class Point { public: ... bool operator==(const Point &pt) const; bool operator!=(const Point &pt) const; }; bool Point::operator==(const Point &pt) const return (x == pt.x && y == pt.y); // x, y가 모두 같으면 true } bool Point::operator!=(const Point &pt) const return (x != pt.x || y != pt.y); // x, y 중 하나라도 다르면 true

증감연산자 1/2 class Point { public: ... Point &operator++(void); const Point operator++(int); const Point operator--(int); };

증감연산자 2/2 Point &Point::operator++(void) { ++x, ++y; return *this; } const Point Point::operator++(int) Point temp = *this; ++*this; return temp; const Point Point::operator--(int) --*this;

인덱스연산자 1/2 class Point { public: ... int &operator[](int index); }; int &Point::operator[](int index) if(index == 0) return x; return y; }

인덱스연산자 2/2 #include <iostream> #include "Point.h" using namespace std; int main(void) { Point pt(10, 20); cout << pt[0] << endl; // x좌표 cout << pt[1] << endl; // y좌표 return 0; }

new, delete 연산자 class Point { public: ... void *operator new(size_t size); void operator delete(void *p); }; void *Point::operator new(size_t size) return malloc(size); } void Point::operator delete(void *p) free(p);

<<, >> 연산자 #include <iostream> using namespace std; class Point { public: ... friend ostream &operator<<(ostream &os, const Point &pt); friend istream &operator>>(istream &is, Point &pt); }; ostream &operator<<(ostream &os, const Point &pt) os << "(" << pt.x << ", " << pt.y << ")"; return os; } istream &operator>>(istream &is, Point &pt) is >> pt.x; is >> pt.y; return is;

Chapter 13 상속

상속 1/3 // Parent.h class Parent // 부모를 모델링 한 클래스 { public: Parent(void); // 생성자 ~Parent(void); // 소멸자 void Character(void); // 성품 출력 void Appearance(void); // 외모 출력 void Wealth(void); // 재산 출력 private: int money; // 돈 저장 };

상속 2/3 #include <iostream> #include "Parent.h" using namespace std; Parent::Parent(void) { money = 1000000000; // 십억 원 } Parent::~Parent(void) void Parent::Character(void) cout << "차분한 성품" << endl; void Parent:: Appearance(void) cout << "잘생긴 외모" << endl; void Parent::Wealth(void) cout << "재산: " << money << "원" << endl;

상속 3/3 // Child.h #include "Parent.h“ class Child : public Parent { };

기능의 추가 1/2 // Child.h #include "Parent.h" class Child : public Parent { public: Child(); // 생성자 ~ Child(); // 소멸자 void Humanity(void); // 추가된 멤버함수 }; void Child::Humanity(void) cout << "넘치는 인간미" << endl; }

기능의 추가 2/2 #include "Child.h“ int main(void) { Child aBoy; aBoy.Character(); // Parent에서 상속 받은 함수 호출 aBoy.Appearance(); // Parent에서 상속 받은 함수 호출 aBoy.Wealth(); // Parent에서 상속 받은 함수 호출 aBoy.Humanity(); // Child에서 추가된 함수 호출 return 0; }

기능의 수정 class Child : public Parent { public: Child(); // 생성자 void Humanity(void); // 추가된 멤버함수 void Character(void); // 수정된 멤버함수 }; void Child::Character(void) cout << "불 같은 성품" << endl; }

기능의 확장 class Child : public Parent { public: Child(); // 생성자 void Humanity(void); // 추가된 멤버함수 void Character(void); // 수정된 멤버함수 void Appearance(void); // 확장된 멤버함수 }; void Child::Appearance(void) Parent::Appearance(); // 기반 클래스에서 정의한 기능 cout << "훤칠한 키" << endl; // 파생 클래스에서 확장된 기능 }

접근권한 private protected public 기반클래스 파생클래스 클래스 외부

생성자와 소멸자 1/2 Parent::Parent(void) { money = 1000000000; cout << "Parent 생성자" << endl; } Parent::~Parent(void) cout << "Parent 소멸자" << endl; Child::Child(void) cout << "Child 생성자" << endl; Child::~Child(void) cout << "Child 소멸자" << endl;

생성자와 소멸자 2/2 class Parent { public: Parent(void); Parent(int money); ... }; Parent::Parent(int money) this->money = money; cout << "Parent 생성자" << endl; } Child::Child(void) : Parent(1000) cout << "Child 생성자" << endl;

다형성

기반 클래스 1/2 // Figure.h class Figure { public: Figure(int x, int y, int width, int height); ~Figure(); void Move(int x, int y); // 도형 이동 void Resize(int width, int height); // 도형 크기 조절 void Draw(); // 도형 그리기 protected: int x; // 중심의 x좌표 int y; // 중심의 x좌표 int width; // 가로 길이 int height; // 세로 길이 };

기반 클래스 2/2 #include <iostream> #include "Figure.h" using namespace std; Figure::Figure(int x, int y, int width, int height) { Move(x, y); Resize(width, height); } void Figure::Move(int x, int y) this->x = x; this->y = y; void Figure::Resize(int width, int height) this->width = width; this->height = height; void Figure::Draw() cout << "Figure::Draw" << endl;

파생 클래스 class Ellipse : public Figure { public: Ellipse(int x, int y, int width, int height); ~Ellipse(); void Draw(); // 오버라이딩 }; Ellipse::Ellipse(int x, int y, int width, int height) : Figure(x, y, width, height) } void Ellipse::Draw() cout << "Draw Ellipse: "; cout << "(" << x << ", " << y << "), "; cout << width << " x " << height; cout << endl;

클래스의 사용 #include "Figure.h“ int main(void) { Ellipse ellipse(30, 20, 50, 20); Triangle triangle(10, 10, 20, 30); Rectangle rectangle(20, 30, 10, 20); ellipse.Draw(); // 타원 그리기 triangle.Draw(); // 삼각형 그리기 rectangle.Draw(); // 사각형 그리기 return 0; }

상속과 포인터 Ellipse ellipse(10, 10, 20, 20); Figure *ptrFigure = &ellipse; 부분 Figure 부분 Figure 부분 Figure Figure Figure Ellipse Triangle Rectangle Ellipse 추가 부분 Triangle 추가 부분 Rectangle 추가 부분 Ellipse ellipse(10, 10, 20, 20); Figure *ptrFigure = &ellipse;

포인터를 이용한 호출 #include "Figure.h" #define FIGURES 10 int main(void) { Figure *figures[FIGURES] = { new Triangle(10, 10, 20, 30), new Rectangle(20, 30, 10, 20), new Ellipse(30, 20, 50, 20), ... new Triangle(50, 0, 30, 20) }; int i; for(i=0 ; i< FIGURES ; i++) figures[i]->Draw(); // 저장된 모든 도형 그리기 delete figures[i]; return 0; }

virtual 함수 // Figure.h class Figure { public: Figure(int x, int y, int width, int height); ~Figure(); void Move(int x, int y); // 도형 이동 void Resize(int width, int height); // 도형 크기 조절 virtual void Draw(); // 도형 그리기 protected: int x; // 중심의 x좌표 int y; // 중심의 x좌표 int width; // 가로 길이 int height; // 세로 길이 };

동적 바인딩 Figure class vptr Figure::Draw() Figure Figure 부분 Ellipse class Ellipse::Draw() Figure 부분 Figure Ellipse Ellipse 추가 부분

virtual 함수의 상속 virtual 속성도 상속됨

순수 virtual 함수 // Figure.h class Figure { public: Figure(int x, int y, int width, int height); ~Figure(); void Move(int x, int y); // 도형 이동 void Resize(int width, int height); // 도형 크기 조절 virtual void Draw() = 0; // 도형 그리기 protected: int x; // 중심의 x좌표 int y; // 중심의 x좌표 int width; // 가로 길이 int height; // 세로 길이 };

virtual 소멸자 1/2 #include "Figure.h" int main(void) { Figure *figures[10] = { new Triangle(10, 10, 20, 30), ... new Triangle(50, 0, 30, 20) }; int i; for(i=0 ; i<10 ; i++) figures[i]->Draw(); // 저장된 모든 도형을 그리기 } delete figures[i]; // 소멸자 호출 return 0;

virtual 소멸자 2/2 class Figure { public: Figure(int x, int y, int width, int height); virtual ~Figure(); void Move(int x, int y); void Resize(int width, int height); virtual void Draw(); protected: int x; int y; int width; int height; };

상속의 형태 is-a 관계: public 상속 Triangle is a Figure. has-a 관계: private/protected 상속 Phone has a camera.

has-a 관계의 예 1/2 class Camera { public: void Photograph(void); void Zoom(int zoom); }; void Camera::Photograph(void) cout << "Take a photo..." << endl; } void Camera::Zoom(int zoom) cout << "Zoom..." << zoom << endl;

has-a 관계의 예 2/2 class Phone { public: void CallUp(int number); void HangUp(void); }; void Phone::CallUp(int number) cout << "Call up... " << number << endl; } void Phone::HangUp(void) cout << "Hang up... " << endl;

컨테인먼트에 의한 has-a 관계 class Phone { public: void CallUp(int number); void HangUp(void); void Photomail(int number); private: Camera camera; }; void Phone::Photomail(int number) camera.Photograph(); CallUp(number); }

private 상속에 의한 has-a 관계 class Phone : private Camera { public: void CallUp(int number); void HangUp(void); void Photomail(int number); }; void Phone::Photomail(int number) Photograph(); CallUp(number); }

컨테인먼트와 상속의 비교 void Phone::Photomail(int number) { camera.Photograph(); CallUp(number); } Photograph();

private 상속 public 상속 private 상속 기반클래스 기반클래스 private private 파생클래스 protected protected private private public public protected protected public public 클래스 외부 클래스 외부

상속의 형태에 따른 접근권한 public 상속 protected 상속 private 상속 public 멤버 public 접근불가

Chapter 14 템플릿

템플릿 함수 템플릿 클래스 템플릿

템플릿의 필요성 void swap(int &a, int &b) { int temp; temp = a; a = b; b = c; } void swap(double &a, double &b) double temp;

함수 템플릿 template <typename T> void swap(T &a, T &b) { T temp; temp = a; a = b; b = c; } template <typename T1, typename T2> void Function(T1 a, T2 b) ...

템플릿의 인스턴스화 #include <iostream> using namespace std; template <typename T> void swap(T &a, T &b) { T temp; temp = a; a = b; b = temp; } int main(void) int a=1, b=2; swap(a, b); // int형을 인자로 받는 swap 함수 호출 cout << a << ", " << b << endl; double c=0.1, d=0.2; swap(c, d); // double형을 인자로 받는 swap 함수 호출 cout << c << ", " << d << endl; return 0;

템플릿의 특화 1/2 #include <iostream> using namespace std; template <typename T> int DataSize(T data) { return sizeof(data); } int main(void) int num = 0; double real = 0.0; char *str = "Good morning!"; cout << DataSize(num) << endl; // int형의 크기 출력 cout << DataSize(real) << endl; // double형의 크기 출력 cout << DataSize(str) << endl; // 문자열의 크기 출력 return 0;

템플릿의 특화 2/2 #include <iostream> using namespace std; template <typename T> int DataSize(T data) { return sizeof(data); } template <> int DataSize(char *data) return strlen(data); int main(void) int num = 0; double real = 0.0; char *str = "Good morning!"; cout << DataSize(num) << endl; cout << DataSize(real) << endl; cout << DataSize(str) << endl;

특화된 함수 정의 방법 template <> int DataSize<char *>(char *data) { return strlen(data); } template <> int DataSize<>(char *data) { return strlen(data); } template <> int DataSize(char *data) { return strlen(data); }

클래스 템플릿의 선언 template <typename T> class Array { public: Array(int size=100); // 생성자 ~Array(void); // 소멸자 bool SetData(int pos, T data); // 데이터 저장 bool GetData(int pos, T &data); // 데이터를 얻음 private: T *pData; // 데이터를 저장하기 위한 포인터 int maxsize; // 데이터 저장 공간의 크기 };

클래스 템플릿의 정의 1/2 template <typename T> Array<T>::Array(int size) { maxsize = size; // 저장 공간의 크기 설정 pData = new T [maxsize]; // 메모리 할당 } Array<T>::~Array(void) delete [] pData; // 메모리 반납

클래스 템플릿의 정의 2/2 template <typename T> bool Array<T>::SetData(int pos, T data) { if(pos < 0 || pos >= maxsize) // 범위를 벗어난 쓰기는 실패 return false; pData[pos] = data; // 데이터 쓰기 return true; // 성공 } bool Array<T>::GetData(int pos, T &data) if(pos < 0 || pos >= maxsize) // 범위를 벗어난 읽기는 실패 data = pData[pos]; // 데이터 읽기

클래스 템플릿의 인스턴스화 #include <iostream> #include "Array.h" using namespace std; int main(void) { Array <double>data(10); int i; double val; for(i=0 ; i<10 ; i++) if(!data.SetData(i, i/10.0)) cout << "Fail to set data" << endl; if(!data.GetData(i, val)) cout << "Fail to get data" << endl; else cout << "Data = " << val << endl; } return 0;