C++ 프로그래밍 07 2007년 2학기 전자정보공학대학 컴퓨터공학부.

Slides:



Advertisements
Similar presentations
3. 메소드와 변수 SCJP 자격증 프로젝트 발표자 : 최선웅. 1. 메 소 드 개 념 2. 메 소 드 양 식 3. 메 소 드 변 수 4. 메 소 드 예 제 5. 참 고 문 헌 / 자 료 목 차.
Advertisements

1 08 배열. 한국대학교 객체지향연구소 2 C 로 배우는 프로그래밍 기초 2 nd Edition 배열  동일한 자료유형의 여러 변수를 일괄 선언  연속적인 항목들이 동일한 크기로 메모리에 저장되는 구조  동일한 자료 유형이 여러 개 필요한 경우에 이용할 수 있는.
Format String Attack! 포맷 스트링 공격 경일대학교 사이버보안학과 학년 남주호.
01_ 가상 함수를 사용한 다형성의 구현 02_ 오버라이딩
ㅎㅎ 구조체 구조체 사용하기 함수 매개변수로서의 구조체 구조체 포인터와 레퍼런스 구조체 배열.
ㅎㅎ 구조체 C++ 프로그래밍 기초 : 객체지향의 시작 구조체 사용하기 함수 매개변수로서의 구조체 구조체 포인터와 레퍼런스
C++ 프로그래밍 년 2학기 전자정보공학대학 컴퓨터공학부.
2장. 프로그램의 기본 구성. 2장. 프로그램의 기본 구성 2-1"Hello, World!" 들여다 보기 /* Hello.c */ #include int main(void) { printf("Hello, World! \n"); return 0;
클래스 class, 객체 object 생성자 constructor 접근 access 제어 이벤트 event 처리.
최윤정 Java 프로그래밍 클래스 상속 최윤정
제 9 장 구조체와 공용체.
C++ 프로그래밍 년 2학기 전자정보공학대학 컴퓨터공학부.
컴퓨터 프로그래밍 기초 [Final] 기말고사
8. 객체와 클래스 (기본).
C++ 프로그래밍 년 2학기 전자정보공학대학 컴퓨터공학부.
11장 구조체와 열거형 구조체의 정의 구조체 변수의 선언 구조체 초기화 및 사용 구조체 재정의 포인터를 이용해서 구조체 사용
Lesson 5. 레퍼런스 데이터형.
제 6장. 생성자와 소멸자 학기 프로그래밍언어및실습 (C++).
Game Programming 03 - Tools of trade
C++ 프로그래밍 년 2학기 전자정보공학대학 컴퓨터공학부.
제 3장. C보다 나은 C++ II.
18장. 헤더 파일과 구현 파일 01_ 헤더 파일과 구현 파일의 사용.
1. C++ 시작하기.
11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.
8장 함수 함수의 필요성 라이브러리 함수와 사용자 정의 함수 함수의 정의, 원형, 호출 배열을 함수 인자로 전달 재귀호출.
SqlParameter 클래스 선문 비트 18기 발표자 : 박성한.
컴퓨터 프로그래밍 기초 #02 : printf(), scanf()
정적 멤버 변수/정적 멤버 함수 - friend 함수/클래스 template
C++ Espresso 제12장 템플릿.
23장. 구조체와 사용자 정의 자료형 2.
14장. 포인터와 함수에 대한 이해.
17장. 문자열 01_ 문자열 사용의 기본 02_ 문자열의 사용.
14. 예외처리.
C++ 프로그래밍 년 2학기 전자정보공학대학 컴퓨터공학부.
11장. 1차원 배열.
C#.
C++ 프로그래밍 년 2학기 전자정보공학대학 컴퓨터공학부.
13. 연산자 오버로딩.
7장 인터페이스와 추상 클래스.
사용자 함수 사용하기 함수 함수 정의 프로그램에서 특정한 기능을 수행하도록 만든 하나의 단위 작업
13. 포인터와 배열! 함께 이해하기 IT응용시스템공학과 김 형 진 교수.
27장. 모듈화 프로그래밍.
쉽게 풀어쓴 C언어 Express 제14장 포인터 활용 C Express Slide 1 (of 22)
Lesson 2. 기본 데이터형.
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
컴퓨터 프로그래밍 기초 - 10th : 포인터 및 구조체 -
20장. 객체지향 프로그래밍 01_ 객체지향 프로그래밍의 시작.
제 4장. 객체 지향 프로그래밍 시작하기 학기 프로그래밍언어및실습 (C++).
컴퓨터 프로그래밍 기초 - 8th : 함수와 변수 / 배열 -
Chapter 08. 함수.
12. 상속 : 고급.
OpenCV 설정 2.21 만든이 딩딩.
Chapter 13. 템플릿(Template) 1
클래스 : 기능 CHAPTER 7 Section 1 생성자(Constructor)
중복 멤버의 처리 조 병 규 한 국 교 통 대 학 교 SQ Lab..
7주차: Functions and Arrays
제 8장. 클래스의 활용 학기 프로그래밍언어및실습 (C++).
3. 모듈 (5장. 모듈).
구조체(struct)와 공용체(union)
Static과 const 선언 조 병 규 한 국 교 통 대 학 교 SQ Lab..
동적메모리와 연결 리스트 컴퓨터시뮬레이션학과 2016년 봄학기 담당교수 : 이형원 E304호,
윤성우의 열혈 C++ 프로그래밍 윤성우 저 열혈강의 C++ 프로그래밍 개정판 Chapter 05. 복사 생성자.
17장. 문자열 01_ 문자열 사용의 기본 02_ 문자열의 사용.
1. 지역변수와 전역변수 2. auto, register 3. static,extern 4. 도움말 사용법
29장. 템플릿과 STL 01_ 템플릿 02_ STL.
어서와 C언어는 처음이지 제21장.
개정판 누구나 즐기는 C언어 콘서트 제13장 동적 메모리 출처: pixabay.
13. 포인터와 배열! 함께 이해하기.
7 생성자 함수.
6 객체.
Presentation transcript:

C++ 프로그래밍 07 2007년 2학기 전자정보공학대학 컴퓨터공학부

Outline Review: 동적 메모리 할당 Review: 문자열 헤더 파일과 구현 파일 객체지향 프로그래밍: CLASS

Review: 메모리 할당 컴퓨터 내의 메모리를 확보하는 일 정적(static) 메모리 할당 동적(dynamic) 메모리 할당 int a[100] : 100개의 정수공간 확보 (400 byte) 정적(static) 메모리 할당 프로그램 실행 전에 메모리 크기 결정 동적(dynamic) 메모리 할당 프로그램 실행 후에 메모리 크기 결정

Review: 정적 할당 vs. 동적 할당 int length = 100; int arr[length]; 배열은 변수를 사용해 크기 지정을 할 수 없다. 동적 할당은 변수를 통해 할 수 있다. int length = 100; int arr[length]; int length = 100; int * arr = new int [length];

Review: 동적 메모리 할당의 규칙(1) new, delete와 new[], delete[] 쌍을 맞춰서 사용하자. 해제한 메모리를 또 해제해서는 안 된다. int * p; p = new int; // 메모리 1개 할당 delete p; // 메모리 1개 해제 p = new int [100]; // 메모리 100개 할당 delete [] p; // 메모리 100개 해제 short* p = new short [100]; // 메모리를 할당한다. delete[] p; // 메모리를 해제한다. delete[] p; // 메모리를 해제한다. Error!

Review: 동적 메모리 할당의 규칙(2) NULL 포인터를 해제하는 것은 안전하다 char* p = NULL; delete p; // 혹은 delete[] p char* p = NULL; p = char [100]; delete [] p; p = NULL;

Review: C 스타일과 C++ 스타일의 문자열 C++: 문자열 클래스(string) 를 사용 C++이 더 개선된 방법이지만 기존에 만들어진 많은 소스 코드에서 C 스타일을 사용하고 있기 때문에 두 가지 스타일을 배워야 한다.

Review: 문자열의 길이와 복사 (C style) #include <iostream> #include <cstring> using namespace std; int main() { char src[] = “Sejong University"; int len = strlen(src); // 1. 길이를 잰다 char* dest = new char [len + 1]; // 2. 메모리 할당 strcpy(dest, src); // 3. 문자열 복사 cout << "src = " << src << "\n"; cout << "dest = " << dest << "\n"; delete[] dest; return 0; }

Review: 문자열의 결합과 비교 (C style) #include <iostream> #include <cstring> using namespace std; int main() { char str1[20] = "abcde"; char str2[] = "fghij"; strcat(str1, str2); cout<<“str1=“<<str1<<“\n”; if ( strcmp( str1, "abcdefghij") == 0) cout << "str1 and \"abcdefghij\" are identical.\n"; if ( strcmp( "123456", str1) != 0) cout << "\"123456\" and str1 are NOT identical.\n"; return0; }

Review: C++ 스타일의 문자열 생성 C++ 스타일의 문자열 변수를 생성하는 예 #include <iostream> #include <string> using namespace std; int main() { string s = "C++ Style~"; cout << s << "\n"; return 0; } [17-21]

Review: 문자열의 복사 (C++ Style) 대입 연산자(=) 사용 실행 결과 #include <iostream> #include <string> using namespace std; int main() { string src = “Sejong University"; string desc; desc = src; // 문자열 복사 cout << "src = " << src << "\n"; cout << "desc = " << desc << "\n"; return 0; }

Review: 문자열의 길이 (C++ Style) string 객체의 맴버함수 size() 사용 #include <iostream> #include <string> using namespace std; int main() { string s1; string s2 = "123"; string s3 = "abcdefg"; cout << "s1 = " << s1.size() << "\n"; cout << "s2 = " << s2.size() << "\n"; cout << "s3 = " << s3.size() << "\n"; return 0; }

Review: 문자열의 결합과 비교(C++ Style) #include <iostream> #include <string> using namespace std; int main() { string str1 = "abcde"; string str2 = "fghij"; str1 = str1 + str2; if ( str1 == "abcdefghij“ ) cout << "str1 and \"abcdefghij\" are identical.\n"; if ( "123456" != str1 ) cout << "\"123456\" and str1 are NOT identical.\n"; return 0; }

Review: 문자열의 검색 (C++ Style) string 객체의 맴버함수 find( ) 사용 #include <iostream> #include <string> using namespace std; int main() { string text = "Napster's pay-to-play service is officially out, " "and we have a review of the now-legit Napster. " "We also size up its companion music player from Samsung."; cout<< text <<“\n”; cout << "Offset of 'official' = " << text.find( "official" ) << "\n"; }

Review: 문자열의 일부분 얻기(C++ Style) string 객체의 맴버함수 substr( ) 사용 #include <iostream> #include <string> using namespace std; int main() { string path = "c:\\My Document\\Pictures\\33.jpg"; int len = path.size(); string ext = path.substr( len - 3, 3); cout << "extention = " << ext << "\n"; return 0; }

헤더 파일과 구현 파일

#include 지시문(1) 하나의 소스 파일로 된 예제 소스 코드 #include <iostream> #include <cmath> using namespace std; struct Point { int x, y; }; double Distance(Point p1, Point p2); int main() // 생략 double dist_a_b = Distance(a, b); } double Distance(Point p1, Point p2)

#include 지시문(2) #include 지시문을 사용해서 두 개의 소스 파일로 나누어 보자. // Example.h struct Point { int x, y; }; double Distance(Point p1, Point p2); // Example.cpp #include <iostream> #include <cmath> using namespace std; #include “Example.h” int main() { // 생략 double dist_a_b = Distance(a, b); } double Distance(Point p1, Point p2)

#include 지시문(3) 두 가지 버전의 예제를 비교해보자. [18-3]

헤더파일과 구현파일을 나누는 방법 하나의 소스 코드로 이루어진 프로그램을 여러 개의 헤더 파일과 구현 파일로 나눌 때 다음의 규칙대로 하자. 규칙 1. 공유될 함수가 있는 구현 파일의 이름을 따서, 헤더 파일을 만든다. 규칙 2. 이 헤더 파일에 공유될 함수의 원형을 적어준다. 규칙 3. 공유될 함수를 호출할 구현 파일에서는 이 헤더 파일을 포함한다. 규칙 4. 구현 파일에서는 자기 자신에 대한 헤더 파일을 포함한다.

실전 테스트 (1) 다음의 세 구현 파일이 제대로 컴파일 될 수 있도록 고치고, 헤더 파일도 추가하자. // A.cpp void A1() { A2(); } void A2() B1(); B2(); // B.cpp void B1() { } void B2() // Example.cpp int main() { A1(); B1(); return 0; }

실전 테스트 (2) 세 구현 파일의 호출 관계를 그림으로 그려보자. [18-7]

실전 테스트 (3) 앞에서 배운 규칙대로 한 결과 // A.h void A1(); void A2(); // B.h void B1(); void B2(); // B.cpp #include “B.h” void B1() { } void B2() // A.cpp #include “A.h” #include “B.h” void A1() { A2(); } void A2() B1(); B2(); // Example.cpp #include “A.h” #include “B.h” int main() { A1(); B1(); return 0; }

다른 파일에 있는 구조체 사용하기 (1) 하나의 소스 파일로 된 예제 소스 코드 struct Point { int x, y; }; double Distance(const Point& pt1, const Point& pt2) // 이 함수의 내용은 생략한다. return 0.0f; } int main() // 두 점을 만든다. Point a = {100, 100}; Point b = {200, 200}; // 함수를 호출한다. double dist; dist = Distance(a, b); return 0;

다른 파일에 있는 구조체 사용하기 (2) 여러 개의 파일로 나누어 보자. // Point.h struct Point { int x, y; }; // Example2.h double Distance(const Point& pt1, const Point& pt2); // Example2.cpp #include “Point.h” #include “Example2.h” double Distance(const Point& pt1, const Point& pt2) { // 이 함수의 내용은 생략한다. return 0.0f; } // Example1.cpp #include “Point.h” #include “Exaple2.h” int main() { // 두 점을 만든다. Point a = {100, 100}; Point b = {200, 200}; // 함수를 호출한다. double dist; dist = Distance(a, b); return 0; }

다른 파일에 있는 구조체 사용하기 (3) 파일들의 포함 관계를 그림으로 그려보자. [18-10]

다른 파일에 있는 구조체 사용하기 (4) 다른 파일에 있는 구조체를 사용하기 위한 방법을 정리해보자. 규칙 1. 구조체의 이름을 따서 새로운 헤더 파일을 만든다. 규칙 2. 이 헤더 파일에 구조체의 정의 부분을 위치시킨다. 규칙 3. 구조체를 사용하는 구현 파일마다 이 헤더 파일을 포함시킨다.

헤더 파일이 두 번 포함되는 것 막기 전처리기를 사용해서 헤더 파일의 중복 포함을 막는 예 중복 포함을 막는 방법 정리 헤더 파일의 이름을 따서 심볼을 만든다 ( 예: POINT_H ) 헤더 파일의 제일 앞에 이 심볼을 사용해서 #ifndef, #define 명령을 추가한다. 헤더 파일의 제일 끝에 #endif를 추가한다. // Point.h #ifndef POINT_H #define POINT_H struct Point { int x, y; }; #endif

표준 라이브러리의 헤더 파일 표준 라이브러리의 헤더 파일은 <> 를 사용해서 포함한다. 우리가 만든 헤더 파일은 “”를 사용해서 포함한다. <> 를 사용한 경우에는 컴파일러와 함께 표준 라이브러리 설치된 디렉토리에서 헤더 파일을 찾는다. 반면에 “”를 사용한 경우에는 여러 분이 작업 중인 프로젝트가 위치한 디렉토리에서 헤더 파일을 찾는다. #include <iostream> #include <string> #include <cmath> #include “Example1.h”

객체 지향 프로그래밍의 이해 (Object Oriented Programming)

객체지향 프로그래밍의 비유(1) 객체지향 프로그래밍은 부품을 모아서 조립하는 과정이 비유할 수 있다. 여기서 객체를 부품이라고 볼 수 있다. [20-1]

객체지향 프로그래밍의 비유(2) 부품별로 분업할 수 있는 것처럼, 객체를 만들 때도 자신의 객체에 대해서만 노력을 집중할 수 있다. 제가 발생한 경우에 해당 부품만 교체하면 되듯이, 객체에 문제가 있는 경우에는 해당 객체만 고치면 된다. [20-2]

객체지향 프로그래밍의 비유(3) 하나의 부품을 여러 제품에 사용할 수 있는 것처럼, 잘 만들어 놓은 객체는 다음 번 프로젝트에도 재사용할 수 있다. 부품들의 규격이 정해져 있어야 조립이 가능한 것처럼, 객체간의 연결 부분도 잘 약속되어 있어야 한다. [20-4] [20-5]

클래스(Classes)와 객체(Objects) (1) 클래스와 객체는 ‘붕어빵 틀’과 ‘붕어빵’의 관계다. 혹은 ‘제품의 설계도’와 ‘제품’의 관계라고 말할 수도 있다. [20-6]

클래스(Classes)와 객체(Objects) (2) 문법적인 측면에서 바라본 클래스와 객체 [20-7]

캡슐화(Encapsulation) 캡슐화란 약속되지 않은 부분은 감싸서 숨겨버리는 것을 말한다. 캡슐화를 통해서 정보은닉을 달성할 수 있다. [20-10]

상속(Inheritance) 상속이란 기존 클래스를 토대로 새로운 클래스를 만드는 방법을 말한다. 예) 상속 모형 예) 붕어빵 틀을 상속받아서 수염 달린 붕어빵 틀을 만들기

다형성(Polymorphism)(1) 다형성이란 서로 다른 객체를 동일한 방식으로 명령을 내릴 수 있는 성질을 말한다. 이 때 서로 다른 객체들은 같은 명령을 받지만 제각기 다른 방식으로 명령을 수행할 수 있다. 예) 백열들과 삼파장 램프는 동일한 소켓에 끼워서 사용할 수 있다. [20-13]

다형성 (2) 문서 저장 객체와 HTML 저장 객체의 예 [20-14]

클래스와 객체

클래스의 정의 Point 클래스를 정의하는 예 // Point 클래스를 정의한다. class Point { public: // 멤버 변수들 int x, y; // 멤버 함수 void Print() cout << "( " << x << ", " << y << ")\n"; } };

클래스의 정의 Point 클래스를 정의하는 예

객체의 생성과 사용(1) 클래스 객체를 생성하고 사용하는 예 // 객체를 생성한다. Point pt1, pt2; pt1.x = 100; pt1.y = 100; pt2.x = 200; pt2.y = 200; // pt1, p2의 내용을 출력한다. pt1.Print(); pt2.Print();

객체의 생성과 사용(2) Print() 함수에서 사용하는 x, y의 의미 [21-3]

일반 함수와 멤버 함수의 차이점 다음과 같은 차이점을 가지고 있다. 외부에서 멤버 함수를 호출하기 위해서는 객체의 이름을 명시해주어야 한다. 멤버 함수 안에서는 객체의 이름을 명시하지 않고 멤버에 접근할 수 있다. 외부에서 접근 할 수 없도록 설정된 멤버라 할지라도 멤버 함수 안에서는 접근할 수 있다.

멤버 함수의 위치 클래스의 정의 바깥쪽에 멤버 함수를 정의한 예 class Point { public: // 멤버 변수 int x, y; // 멤버 함수 void Print(); }; void Point::Print() cout << "( " << x << ", " << y << ")\n"; }

멤버 함수 안에서의 이름 충돌 클래스의 정의 바깥쪽에 멤버 함수를 정의한 예 class Point { public: // 멤버 변수 int x, y; // 멤버 함수 void Print(); }; void Point::Print() int x = 333; cout << "( " << x << ", " << y << ")\n"; }

객체를 사용한 초기화와 대입 일반 변수와 같은 방식으로 초기화와 대입 가능 Point pt1, pt2; pt1.x = 100; pt1.y = 100; pt2.x = 200; pt2.y = 200; // pt1을 사용해서 새로운 pt3를 초기화 한다. Point pt3 = pt1; pt3.Print(); // pt2을 pt3에 대입한다. pt3 = pt2;

생성자와 소멸자 생성자는 객체를 생성할 때 자동으로 호출되는 함수이다. 소멸자는 객체를 소멸할 때 자동으로 호출되는 함수이다. 그러므로 생성자는 객체를 사용할 수 있도록 초기화 하는 코드를 넣기에 알맞은 장소이다. 소멸자는 객체를 소멸할 때 자동으로 호출되는 함수이다. 그러므로 소멸자는 객체가 사용한 리소스를 정리하는 코드를 넣기에 알맞은 장소이다.

디폴트 생성자(Default Constructors) 디폴트 생성자의 추가 class Point { public: int x, y; void Print(); Point(); }; Point::Point() x = 0; y = 0; } // 실제 실행 시.. Point pt; // 생성자가 호출된다. pt.Print();

인자가 있는 생성자(1) 인자가 있는 생성자의 추가 class Point { public: int x, y; void Print(); Point(); Point(int initialX, int initialY); }; Point::Point(int initialX, int initialY) x = initialX; y = initialY; } // 중간 생략 Point pt(3, 5); pt.Print();

인자가 있는 생성자(2) 생성자로의 인자 전달

복사생성자(Copy Contructors)(1) class Point { public: int x, y; void Print(); Point(); Point(int initialX, int initialY); Point(const Point& pt); }; Point::Point(const Point& pt) cout << "복사 생성자 호출됨!!\n"; x = pt.x; y = pt.y; } // 중간 생략 Point pt1(100, 100), pt2(200, 200); // pt1을 사용해서 새로운 pt3를 초기화 한다. Point pt3 = pt1; pt3.Print(); // pt2을 pt3에 대입한다. pt3 = pt2; 복사 생성자의 추가 [21-8]

복사생성자(Copy Contructors)(2) 복사 생성자는 자기 자신의 타입에 대한 레퍼런스를 인자로 받는 생성자다. 그러므로 다음의 두 가지 원형 중 한 가지 모습을 가질 수 있다. 다음과 같은 두 가지 방식으로 복사 생성자를 호출할 수 있다. Point( Point& pt ); Point( const Point& pt ); Point pt1; Point pt2 = pt1; Point pt3( pt1 );

얕은 복사와 깊은 복사 기본적으로 제공되는 복사 생성자는 얕은 복사를 하도록 구현되어 있다. 깊은 복사가 필요하다면 별도의 복사 생성자를 만들어야 한다. [21-11]

반드시 생성자가 필요한 경우 멤버 변수중에 레퍼런스 변수 혹은 Const 속성의 변수가 있는 경우에는 반드시 생성자에서 초기화 해주어야 한다. class NeedConstructor { public: const int maxCount; int& ref; int sample; NeedConstructor(); }; NeedConstructor::NeedConstructor() : maxCount(100), ref(sample) sample = 200; }

소멸자(1) 소멸자를 사용해서 할당한 메모리를 해제하는 예 class DynamicArray { public: int* arr; DynamicArray(int arraySize); ~DynamicArray(); }; DynamicArray::DynamicArray(int arraySize) // 동적으로 메모리를 할당한다. arr = new int [arraySize]; } DynamicArray::~DynamicArray() // 메모리를 해제한다. delete[] arr; arr = NULL;

소멸자(2) 소멸자를 사용해서 할당한 메모리를 해제하는 예 int main() { // 몇 개의 정수를 입력할지 물어본다. 소멸자를 사용해서 할당한 메모리를 해제하는 예 int main() { // 몇 개의 정수를 입력할지 물어본다. int size; cout << "몇 개의 정수를 입력하시겠소? "; cin >> size; // 필요한 만큼의 메모리를 준비한다. DynamicArray da(size); // 정수를 입력 받는다. for (int i = 0; i < size; ++i) cin >> da.arr[i]; // 역순으로 정수를 출력한다. for (i = size - 1; i >= 0; --i) cout << da.arr[i] << " "; cout << "\n"; // 따로 메모리를 해제해 줄 필요가 없다. return 0; }

소멸자(3) DynamicArray 객체를 생성한 모습 [21-20]

접근 권한 설정하기(1) 멤버의 접근 권한을 설정하는 예 class AccessControl { public: char publicData; void publicFunc() {}; protected: int protectedData; void protectedFunc() {}; private: float privateData; void privateFunc() {}; }; int main() // 객체를 생성하고, 각 멤버에 접근해보자 AccessControl ac; ac.publicData = 'A'; // 성공 ac.publicFunc(); // 성공 ac.protectedData = 100; // 실패 ac.protectedFunc(); // 실패 ac.privateData = 4.5f; // 실패 ac.privateFunc(); // 실패 return 0; } 멤버의 접근 권한을 설정하는 예

접근 권한 설정하기(2) 멤버의 접근 권한 설정하기 접근 권한 키워드에 대한 요약 (뒤에서 더욱 자세히 분류) [21-23] public : 외부에서의 접근을 허용한다. protected, private : 외부에서 접근할 수 없다. [21-23]

접근자 접근자란 외부에서 접근이 거부된 멤버 변수의 값을 읽거나, 변경하려는 용도의 멤버 함수를 말한다. class Point { public: void SetX(int value) if (value < 0) x = 0; else if (value > 100) x = 100; else x = value; } int GetX() {return x;}; // 중간 생략 private: // 멤버 변수 int x, y; };

정적 멤버 (Static Members) 정적 멤버란 모든 객체들이 공유하는 멤버를 말한다. [21-29]

정적 멤버를 사용한 객체의 개수 세기(1) class Student { public: string name; // 이름 int sNo; // 학번 Student(const string& name_arg, int stdNumber); ~Student(); // 정적 멤버들 static int student_count; static void PrintStdCount(); }; // 정적 멤버 변수 int Student::student_count = 0; // 정적 멤버 함수 void Student::PrintStdCount() cout << "Student 객체 수 = " << student_count << "\n"; }

정적 멤버를 사용한 객체의 개수 세기(2) Student::Student(const string& name_arg, int stdNumber) { // 학생 객체의 수를 증가시킨다. student_count++; name = name_arg; sNo = stdNumber; } Student::~Student() // 학생 객체의 수를 감소시킨다. student_count--; void Func() Student std1("Bill", 342); Student std2("James", 214); Student::PrintStdCount();

정적 멤버를 사용한 객체의 개수 세기(3) 정적 멤버를 사용해서 객체의 개수를 세는 예 int main() { Student::PrintStdCount(); Student std("Jeffrey", 123); Func(); return 0; }

헤더 파일과 소스 파일로 나누기 헤더 파일에 넣어야 할 것과 구현 파일에 넣어야 할 것 Point 클래스 예제를 헤더 파일과 구현 파일로 나눈 예 [21-32]

인라인 함수 = 함수를 인라인으로 만들면 실제로 함수가 호출되는 대신에, 함수를 호출한 위치에 함수의 내용이 그대로 옮겨진다. // 인라인 함수 inline void Func() { cout << “왜 인라인 함수를 쓰지?\n”; cout << “도대체 인라인이 뭐야!!\n”; cout << “뭐! 내가 인라인이야?\n”; } int main() // 인라인 함수를 호출한다. Func(); return 0; = int main() { // 인라인 함수를 호출한다. cout << “왜 인라인 함수를 쓰지?\n”; cout << “도대체 인라인이 뭐야!!\n”; cout << “뭐! 내가 인라인이야?\n”; return 0; }

인라인 함수를 만드는 법 멤버 함수를 인라인으로 만드는 방법에는 두 가지가 있다. 클래스의 내부에 정의한 멤버 함수들은 자동으로 인라인 함수가 된다. 클래스의 외부에 정의한 멤버 함수는 함수의 정의 앞에 inline 키워드를 추가한다. class CPoint { // 중간 생략 }; inline void CPoint::SetX(int value) if (value < 0) x = 0; else if (value > 100) x = 100; else x = value; } inline void CPoint::SetY(int value) if (value < 0) y = 0; else if (value > 100) y = 100; else y = value;

인라인 함수의 사용 규칙 인라인 함수는 헤더 파일에 위치해야 한다. 크기가 작은 함수만 인라인으로 만드는 것이 좋다. 인라인 함수가 클래스의 정의 내부에 있는 경우 => 어차피 클래스의 정의는 헤더 파일에 위치하므로 특별히 신경 써줄 것이 없다. 인라인 함수가 클래스의 정의 외부에 있는 경우 => 함수의 정의를 반드시 헤더 파일에 위치시켜야 한다. 크기가 작은 함수만 인라인으로 만드는 것이 좋다. 크기가 큰 함수를 인라인으로 만들면 실행 파일의 크기가 커지기 때문에 실행 성능이 낮아질 수 있다.

Const 함수 다음의 조건을 만족 하는 함수만 Const 함수로 만들 수 있다. 멤버 변수의 값을 변경하지 않는 멤버 함수 멤버 함수를 Const 함수로 만들면 좋은 점 다른 개발자가 “아, 이 함수는 멤버 변수의 값을 변경하지 않는구나”라고 생각하게 만든다. 실수로 멤버 변수의 값을 바꾸려고 하면, 컴파일러가 오류 메시지를 통해서 알려준다. 객체가 Const 속성을 가진 경우에는 Const 함수만 호출할 수 있다. [12-36]

Const 함수의 사용(1) 가능한 모든 함수를 Const 함수로 만드는 것이 좋다. class Point { public: // 멤버 함수 void Print() const; // 생성자들 Point(); Point(int initialX, int initialY); Point(const Point& pt); // 접근자 void SetX(int value); void SetY(int value); int GetX() const {return x;} int GetY() {return y;} private: // 멤버 변수 int x, y; };

Const 함수의 사용(2) Const 객체를 통해서 멤버 함수를 호출하는 예 매개변수 pt가 Const 객체이지만 CPoint::GetX()는 Const 함수이기 때문에 호출될 수 있다. 그러나, CPoint::GetY() 는 Const 함수가 아니기 때문에 컴파일 오류를 발생시킨다. void Area( const Point& pt) { // (0,0)과 pt 가 이루는 사각형의 면적을 구한다. int area = pt.GetX() * pt.GetY(); // Error // 결과 출력 cout << "(0, 0)과 이 점이 이루는 사각형의 면적 = " << area << "\n"; }

멤버 함수에 대한 포인터(1) 멤버 함수에 대한 포인터 타입을 정의하는 예 #include "Point.h" // void XX() 형태의 함수에 대한 포인터 typedef void (*FP1)(int); // void Point::XX() 형태의 멤버 함수에 대한 포인터 typedef void (Point::*FP2)(int); int main() { // 객체를 생성한다. Point pt(50, 50); // FP1, FP2를 사용해서 Print() 함수를 가리킨다. // FP1 fp1 = &Point::SetX; // 에러 FP2 fp2 = &Point::SetX; // 성공 // 함수 포인터를 사용해서 함수 호출 (pt.*fp2)(100); // 내용 출력 pt.Print(); return 0; }

멤버 함수에 대한 포인터(2) 멤버 함수의 포인터 타입 정의와 호출

객체의 배열(1) 객체의 배열을 정의하는 경우 디폴트 생성자로 초기화 된다. #include "Point.h" int main() { // 점 3개의 배열 Point arr[3]; // 모든 원소를 출력한다. for (int i = 0; i < 3; ++i) arr[i].Print(); return 0; }

객체의 배열(2) 객체의 배열을 초기화하는 예 int main() { // 점 3개의 배열 Point arr[3] = { Point(100, 100), Point(50, 100), Point( 10, 10) }; // 모든 원소를 출력한다. for (int i = 0; i < 3; ++i) arr[i].Print(); return 0; }

객체의 동적인 생성 동적 메모리 할당을 사용해서 객체를 생성하는 예 Point pt(50, 50); Point* p1 = new Point(); // 디폴트 생성자 사용 Point* p2 = new Point(100, 100); // 인자있는 생성자 사용 Point* p3 = new Point( pt); // 복사 생성자 사용 p1->Print(); p2->Print(); p3->Print(); delete p1; delete p2; delete p3;

생성자와 소멸자의 호출 시점(1) 동적 메모리 할당을 사용한 경우의 생성자와 소멸자의 호출 시점을 알아보자. int main { Point pt(100, 100); Point* p = 0; p = new Point(50, 50); pt.Print(); p->Print(); // 동적으로 생성한 객체를 해제한다. delete p; p = NULL; return 0; }

생성자와 소멸자의 호출 시점(2) 생성자와 소멸자의 호출 시점을 표로 정리

클래스 안에 넣을 수 있는 다른 것들 열거체나 typedef을 클래스 안에서 정의하는 예 class Point { public: enum { MIN_X = 0, MAX_X = 100, MIN_Y = 0, MAX_Y = 100 }; typedef int COOR_T; // 좌표의 타입 // 멤버 함수 void Print() const; void Offset(COOR_T x_delta, COOR_T y_delta); void Offset(const Point& pt); // 생성자들 Point(); Point(COOR_T initialX, COOR_T initialY); Point(const Point& pt); // 접근자 void SetX(COOR_T value); void SetY(COOR_T value); COOR_T GetX() const {return x;}; COOR_T GetY() const {return y;}; private: // 멤버 변수 COOR_T x, y; };

This 포인터(1) 멤버 함수 안에서 자기 자신의 주소를 확인하는 예 class WhoAmI { public: int id; WhoAmI(int id_arg); void ShowYourself() const; }; WhoAmI:: WhoAmI(int id_arg) id = id_arg; } void WhoAmI::ShowYourself() const cout << "{ID = " << id << ", this = " << this << "}\n";

This 포인터(2) 멤버 함수 안에서 자기 자신의 주소를 확인하는 예 int main() { // 세 개의 객체를 만든다. WhoAmI obj1( 1); WhoAmI obj2( 2); WhoAmI obj3( 3); // 객체들의 정보를 출력한다. obj1.ShowYourself(); obj2.ShowYourself(); obj3.ShowYourself(); // 객체들의 주소를 출력한다. cout << "&obj1 = " << &obj1 << "\n"; cout << "&obj2 = " << &obj2 << "\n"; cout << "&obj3 = " << &obj3 << "\n"; return 0; }

This 포인터(3) 멤버 함수의 호출과 가상의 코드 [21-50]

연습 student class 를 구현(헤더 파일과 구현파일 사용) 이름, 번호,수학, 영어, 국어 점수의 맴버 변수 총점 및 평균을 구하는 맴버 함수 학생의 내용을 입력 받는 함수 학생의 내용을 이쁘게 출력해 주는 print() 맴버함수 student로 4개의 크기를 갖는 배열을 만들고 내용을 입력하면 출력해 주는 프로그램