Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "C++ 프로그래밍 07 2007년 2학기 전자정보공학대학 컴퓨터공학부."— Presentation transcript:

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

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

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

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

5 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!

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

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

8 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; }

9 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; }

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

11 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; }

12 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; }

13 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; }

14 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"; }

15 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; }

16 헤더 파일과 구현 파일

17 #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)

18 #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)

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

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

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

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

23 실전 테스트 (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; }

24 다른 파일에 있는 구조체 사용하기 (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;

25 다른 파일에 있는 구조체 사용하기 (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; }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

40 클래스와 객체

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

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

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

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

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

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

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

48 객체를 사용한 초기화와 대입 일반 변수와 같은 방식으로 초기화와 대입 가능 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;

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

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

51 인자가 있는 생성자(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();

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

53 복사생성자(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]

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

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

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

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

58 소멸자(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; }

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

60 접근 권한 설정하기(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; } 멤버의 접근 권한을 설정하는 예

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

62 접근자 접근자란 외부에서 접근이 거부된 멤버 변수의 값을 읽거나, 변경하려는 용도의 멤버 함수를 말한다. 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; };

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

64 정적 멤버를 사용한 객체의 개수 세기(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"; }

65 정적 멤버를 사용한 객체의 개수 세기(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();

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

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

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

69 인라인 함수를 만드는 법 멤버 함수를 인라인으로 만드는 방법에는 두 가지가 있다.
클래스의 내부에 정의한 멤버 함수들은 자동으로 인라인 함수가 된다. 클래스의 외부에 정의한 멤버 함수는 함수의 정의 앞에 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;

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

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

72 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; };

73 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"; }

74 멤버 함수에 대한 포인터(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; }

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

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

77 객체의 배열(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; }

78 객체의 동적인 생성 동적 메모리 할당을 사용해서 객체를 생성하는 예 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;

79 생성자와 소멸자의 호출 시점(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; }

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

81 클래스 안에 넣을 수 있는 다른 것들 열거체나 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; };

82 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";

83 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; }

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

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


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

Similar presentations


Ads by Google