chapter 6 구조체. 구조체 struct point { int x;// x좌표 int y;// y좌표 }; struct customer...

Post on 19-Jan-2018

251 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

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

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;

}

구조체의 포인터 #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 50struct Item{

char name[MAX_NAME]; // 품명int price; // 단가int num; // 수량

};

구조체 활용 2/3int 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");printf("------------------------------\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("------------------------------\n");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{ char c;int i;short s;};int main(void){ printf("s1 의 크기 : %d\n", sizeof(struct s1));printf("s2 의 크기 : %d\n", sizeof(struct s2));return 0;}

구조체 멤버변수의 정렬 2/2

char c

short s

int i

정렬단위

정렬단위

char c

short s

int i

정렬단위

정렬단위

정렬단위

struct s1 struct s2

지역변수

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 9C 문법의 확장

변수선언

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/2namespace Graphics{ int value;void Initialize(void){ ...}}namespace Network{ int value;void Initialize(void){ ...}}int main(void){ Graphics::Initialize();Network::Initialize();...return 0;}

using namespace Graphics;using Graphics::Initialize;

범위지정 연산자 2/2int value = 0; // 전역변수 선언

int main(void){

int value = 10; // 지역변수 선언value++; // 지역변수 참조::value++; // 전역변수 참조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){ return a+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);void output(int num){ 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++; // 버튼을 한번 누름counter++; // 버튼을 한번 누름cout << counter << endl; // 카운터 값을 출력

return 0;}

멤버함수를 통한 멤버변수 접근 2/2class 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(); // 버튼을 한번 누름ct.Click(); // 버튼을 한번 누름cout << ct.GetCount(); // 카운터 값을 출력cout << endl;return 0;

}

생성자와 소멸자class Counter{public:

Counter(void); // 생성자~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/4class 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/4Array::Array(void){

maxsize = 100; // 크기를 기본 값으로 설정pData = new int [maxsize]; // 메모리 할당

}Array::Array(int size){

maxsize = size; // 크기를 주어진 값으로 설정pData = new int [maxsize]; // 메모리 할당

}Array::~Array(void){

delete [] pData; // 메모리 반납}

생성자의 인자 3/4bool 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) // 범위를 벗어난 읽기는 실패return false;

data = pData[pos]; // 데이터 읽기return true; // 성공

}

생성자의 인자 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;

elsecout << "Data = " << val << endl;

}return 0;

}

복사 생성자

Array::Array(const Array &data){

maxsize = data.maxsize;pData = data.pData;

}Array::Array(const Array &data){

maxsize = data.maxsize;pData = data.pData;

}Array::Array(const Array &data){

maxsize = data.maxsize; // 크기를 같게 설정

pData = new int [maxsize]; // 메모리 공간 할당memcpy(pData, data.pData, maxsize); // 데이터 영역

복사}

포함된 클래스의 생성자 호출 1/2class Container{public:

Container(int size);// ...

private:Array data;

};

Container::Container(int size) : data(size){

}

포함된 클래스의 생성자 호출 2/2class Container{public:

Container(int size);// ...

private:Array data(10); // 컴파일 에러

};Container::Container(int size){

data(size); // 컴파일 에러}Container::Container(int size){

Array data(size); // 지역변수 선언}

파일의 분할

ClassA.cpp ClassA.h

ClassB.cpp ClassB.h

ClassC.cpp ClassC.h

main.cpp

파일 분할의 예 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) // 카운터를 리셋{

count = 0;}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(); // 버튼을 한번 누름ct.Click(); // 버튼을 한번 누름cout << ct.GetCount(); // 카운터 값을 출력cout << endl;return 0;

}

inline 멤버함수 1/2class 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){

count = 0;}

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/3int 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

“ 문근영 " name

19

age

0x1100

this

s2

“ 전지현 " name

27

age

0x1200

this

s3

int Student::GetCount(){ return count;}

3

count

멤버함수 /멤버변수 static 멤버함수 /멤버변수

클래스의 외부

this

this

void Student::Show(){ cout << name << age;}

int main(){ ...}

③ ④ ⑩ ⑦

⑤ ⑨

this 포인터 2/2

int main(void){ ... s1.Show(); ...}

void Student::Show(){ cout << name << age;}

void Student::Show(Student *this){ cout << this->name << this->age;}

int main(void){ ... Student::Show(s1.this); ...}

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;count++;

}

멤버함수의 포인터 1/3#define MAX_NAME 20class 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/3int 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){

Student *pa = (Student *)a;Student *pb = (Student *)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++)

talent[i].Show();return 0;

}

const 상수

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

const 포인터

const int *ptr = NULL int num[2];ptr = num;ptr++;*ptr = 20; // 컴파일 에러

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.hclass 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;++x, ++y;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) 호출p1.Show();p3.Show();return 0;

}

단항연산자 호출 과정

Point Point::operator++(){

++x, ++y;return *this;

}

p2 = ++p1;

p2 = p1.operator++();

Point Point::operator++(int){

Point temp = *this;++x, ++y;return temp;

}

p2 = p1++;

p2 = p1.operator++(int);

이항연산자 정의

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;

}

이항연산자 호출 과정

Point Point::operator+(Point pt){

Point temp;temp.x = x + pt.x;temp.y = y + pt.y;return temp;

}

a = b + c;

a = b.operator+(c);

friend 함수의 필요성

Point p1(10, 20), p2;p2 = p1 * 2;

Point p1(10, 20), p2;p2 = 2 * p1;

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){

Point temp;temp.x = mag * pt.x;temp.y = mag * pt.y;return temp;

}

friend 연산자 함수 호출#include <iostream>#include "Point.h“int main(void){

Point p1(10, 20), p2;p2 = p1 * 2; // 멤버함수 호출 p2.Show();p2 = 2 * p1; // friend 함수 호출p2.Show();return 0;

}

friend 연산자 함수 호출 과정

Point Point::operator*(int mag, Point pt){

Point temp;temp.x = mag * pt.x;temp.y = mag * pt.y;return temp;

}

a = 2 * b;

a = operator*(2, b);

연산자 함수의 인자

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){

Point temp;temp.x = x * mag;temp.y = y * mag;return temp;

}

연산자 함수 상수화

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/2class Point{public:

...Point &operator=(const Point &pt);Point &operator+=(const Point &pt);Point &operator-=(const Point &pt);Point &operator*=(int mag);Point &operator/=(int div);...

};

대입연산자 1/2Point &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;return *this;}Point &Point::operator-=(const Point &pt){ x -= pt.x; y -= pt.y;return *this;}Point &Point::operator*=(int mag){ x *= mag; y *= mag;return *this;}Point &Point::operator/=(int div){ x /= div; y /= div;return *this;}

산술연산자 1/2class 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/2Point 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/2class Point{public:

...Point &operator++(void);Point &operator--(void);const Point operator++(int);const Point operator--(int);...

};

증감연산자 2/2Point &Point::operator++(void){

++x, ++y;return *this;

}Point &Point::operator--(void){

--x, --y;return *this;

}const Point Point::operator++(int){

Point temp = *this;++*this;return temp;

}const Point Point::operator--(int){

Point temp = *this;--*this;return temp;

}

인덱스연산자 1/2class 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.hclass 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(); // 생성자~ Child(); // 소멸자void Humanity(void); // 추가된 멤버함수void Character(void); // 수정된 멤버함수

};

void Child::Character(void){

cout << " 불 같은 성품 " << endl;}

기능의 확장

class Child : public Parent{public:

Child(); // 생성자~ Child(); // 소멸자void Humanity(void); // 추가된 멤버함수void Character(void); // 수정된 멤버함수void Appearance(void); // 확장된 멤버함수

};void Child::Appearance(void){

Parent::Appearance(); // 기반 클래스에서 정의한 기능

cout << "훤칠한 키 " << endl; // 파생 클래스에서 확장된 기능}

접근권한

private

protected

public

기반클래스

private

protected

public

파생클래스

클래스 외부

생성자와 소멸자 1/2Parent::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/2class 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.hclass 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;}

상속과 포인터

Figure부분

Ellipse추가 부분

Figure

Ellipse

Figure부분

Triangle추가 부분

Figure

Triangle

Figure부분

Rectangle추가 부분

Figure

Rectangle

Ellipse ellipse(10, 10, 20, 20);Figure *ptrFigure = &ellipse;

포인터를 이용한 호출#include "Figure.h"#define FIGURES 10int 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(); // 저장된 모든 도형 그리기

for(i=0 ; i< FIGURES ; i++)delete figures[i];

return 0;}

virtual 함수

// Figure.hclass 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부분

Ellipse추가 부분

FigureEllipse

vptr

Figure::Draw()Figure부분

Figure

vptr

Ellipse::Draw()

Figure class

Ellipse class

virtual 함수의 상속

virtual 속성도 상속됨

순수 virtual 함수

// Figure.hclass 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(); // 저장된 모든 도형을 그리기 }for(i=0 ; i<10 ; i++){

delete figures[i]; // 소멸자 호출}return 0;}

virtual 소멸자 2/2class 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/2class 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/2class 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);

}

void Phone::Photomail(int number){

Photograph();CallUp(number);

}

private 상속public 상속 private 상속

private

protected

public

기반클래스

private

protected

public

파생클래스

클래스 외부

private

protected

public

기반클래스

private

protected

public

파생클래스

클래스 외부

상속의 형태에 따른 접근권한

public 상속 protected 상속 private 상속

public 멤버 public protected privateprotected 멤버 protected protected private

private 멤버 접근불가 접근불가 접근불가

Chapter 14템플릿

템플릿

함수 템플릿클래스 템플릿

템플릿의 필요성

void swap(int &a, int &b){ int temp;temp = a;a = b;b = c;}void swap(double &a, double &b){ double temp;temp = a;a = b;b = c;}

함수 템플릿

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/2template <typename T>Array<T>::Array(int size){

maxsize = size; // 저장 공간의 크기 설정pData = new T [maxsize]; // 메모리 할당

}

template <typename T>Array<T>::~Array(void){

delete [] pData; // 메모리 반납}

클래스 템플릿의 정의 2/2template <typename T>bool Array<T>::SetData(int pos, T data){

if(pos < 0 || pos >= maxsize) // 범위를 벗어난 쓰기는 실패return false;

pData[pos] = data; // 데이터 쓰기return true; // 성공

}template <typename T>bool Array<T>::GetData(int pos, T &data){

if(pos < 0 || pos >= maxsize) // 범위를 벗어난 읽기는 실패return false;

data = pData[pos]; // 데이터 읽기return true; // 성공

}

클래스 템플릿의 인스턴스화

#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;

elsecout << "Data = " << val << endl;

}return 0;

}

top related