C++ Programming 클래스와데이터추상화 Seo, Doo-okok clickseo@gmail.com http://www.clickseo.com
목 차 객체지향프로그래밍 클래스와객체 2
객체지향프로그래밍 객체지향언어 (Object-Oriented Language) 프로그램을명령어의목록으로보는시각에서벗어나여러개의 독립된단위, 즉 객체 (Object) 들의모임으로파악 구성요소 : 클래스, 객체, 메소드, 메시지 특징 : 캡슐화, 추상화, 다형성, 상속, 인스턴스, 메시지전달 객체지향언어 : C++, JAVA, C#, Objective-C/C++ 등 인터페이스 ( 멤버함수 ) 내부변수 사용자 구현자 3
객체지향프로그래밍 (cont d) 객체지향언어의 3 가지특징 객체지향언어 캡슐화다형성상속성 정보은닉 다중정의 재정의 단일상속 다중상속 4
객체지향프로그래밍 (cont d) 캡슐화 (encapsulation) 데이터와데이터의행동양식을결정하는코드 ( 절차 ) 를묶는구조 원하는부분을외부로부터숨길수있다. 동작과정보를포함하는블랙박스 (Black Box) 를만들수있다. 데이터 + 캡슐화 인터페이스 데이터 절 차 절 차 5
객체지향프로그래밍 (cont d) 다형성 (polymorphism) 목적은다르지만연관성이있는두가지이상의용도로하나의이름을 사용할수있게하는성질 다형성은함수와연산자에모두적용된다. C++ 에서는 사용자정의자료형 에대해서도다형성으로확장할수있다. USB 인터페이스 6
상속성 (inheritance) 객체지향언어 (cont d) 하나의객체가다른객체의특성을이어받을수있는특성 하나의객체는일반적인동작이나성질들을상속받아자신의특화된동작과성질들을추가할수있다. 날수있는객체 최고고도비행속도날개의수 최고고도비행속도날개의수 새 항공기 최고고도비행속도날개의수 평균수명 헬리콥터 탑재무게엔진의수 카나리아 전투기 여객기 독수리 7
객체지향프로그래밍 클래스와객체 생성자와소멸자 복사생성자 friend 선언 멤버변수와함수의제한 클래스와포인터, 배열 클래스와객체 8
구조체의아쉬움 struct _point int x; int y; 클래스와객체 void OUTPUT(void) cout << x : << x << y : << y << endl; 구조체선언시 데이터를조작 ( 접근 ) 하는함수도묶을수는없을까? 9
클래스 (Class) 클래스와객체 (cont d) 같은목적을가진함수와이함수들이사용하는변수들을한곳에모아서관리하는일종의집합체 ( 새로운자료형 ) 변수 : 애트리뷰트 (attribute) 함수 : 메소드 (method) 클래스 = 멤버변수 + 멤버함수 객체 (Object) 클래스를이용해서정의된자료형의변수의표현 ( 완전한대상체 ) 인스턴스화 (instantiation) : 클래스를기반으로객체를생성하는것 10
클래스 (cont d) 클래스와객체 (cont d) #include <iostream> using std::cout; using std::endl; 클래스 = 멤버변수 + 멤버함수 // 클래스정의 class Point // 멤버변수 int x; int y; // 멤버함수 void OUTPUT(void) cout << "x : " << x << ", y : " << y << endl; int main(void) // 객체생성 Point temp; return 0; int x; int y; void OUTPUT(); Point 11
클래스멤버접근제어 클래스와객체 (cont d) 클래스내의멤버변수또는멤버함수의접근권한부여 private : 동일한클래스의접근만허용 ( 내부접근 ) protected : 클래스와상속받은클래스의접근허용 public : 모든클래스에서접근허용 ( 외부접근 ) public protected private 12
클래스와객체 (cont d) 프로그램예제 : 객체를사용한초기화와대입 #include <iostream> using std::cin; using std::cout; using std::endl; 객체를사용한초기화나대입은 기본적으로구조체와같다 class Point int x; int y; void OUTPUT(void) cout << "x : " << x << ", y : " << y << endl; int main(void) Point a; a.x = 10; a.y = 20; a.output(); Point b = a; // Point b(a); b.output(); return 0; 13
클래스와객체 (cont d) 프로그램예제 : 클래스의내부접근과외부접근 #include <iostream> using std::cin; using std::cout; using std::endl; class Count int i; Count int i; void Increment(); void Increment(void) i++; // 내부접근 int main(void) Count // 외부접근 temp; temp.i = 0; cout << "temp : " << temp.i << endl; temp.increment(); cout << "temp : " << temp.i << endl; return 0; 14
클래스와객체 (cont d) 멤버함수의클래스외부정의 #include <iostream> using std::cout; using std::endl; class Point int x; int y; Point int x; int y; void OUTPUT(); void OUTPUT(void); void Point::OUTPUT(void) cout << "x : " << x << ", y : " << y << endl; int main(void) Point temp; return 0; 15
좋은클래스의설계 클래스와객체 (cont d) 정보은닉 (Information Hiding) 모든멤버변수를 private 으로선언!!! 객체의외부에서객체의멤버변수에직접접근하지못하게하는것. 오직객체의멤버함수를통하여접근하도록하는방법 캡슐화 (Encapsulation) 관련있는데이터와함수를하나의단위로묶는것 class Point int x; int y; void OUTPUT(void); // 다른함수들 void Point::OUTPUT(void) cout << "x : " << x << ", y : " << y << endl; 16
생성자 (Constructor) 생성자와소멸자 객체의생성과동시에호출되는함수 소멸자 (cont d) 클래스의이름과동일한이름의함수 반환하지도않고, 반환되는자료형도선언되지않는다. 생성자를하나도정의하지않으면, 디폴트 (default) 생성자가자동삽입된다. class Point int x; int y; Point() // default 생성자 17
생성자와소멸자 프로그램예제 : 생성자와함수다중정의 #include <iostream> using std::cout; using std::endl; class int Point int int _x; _y; 소멸자 (cont d) 생성자도함수이므로 함수의특징을그대로지닌다. int _x; int _y; Point() Point(int x, int y) Point(); _x = x; _y = y; void main(void) ShowData(void) Point Point(int, int); void ShowData(); cout << "x : " << _x << ", y : " << _y << endl; Point a; Point b(10, 20); a.showdata(); b.showdata(); return 0; 18
생성자와소멸자 프로그램예제 : 생성자와디폴트매개변수 #include <iostream> using std::cout; using std::endl; 소멸자 (cont d) int _x; int _y; Point class Point Point(int = 0, int = 0); int _x, _y; void ShowData(); Point(int x = 0, int y = 0) void _x = x; _y = y; ShowData(void) cout << "x : " << _ x << ", y : " << _y << endl; int main(void) Point a; // Point a(0, 0); Point b(10, 20); a.showdata(); b.showdata(); return 0; 19
소멸자 (Destructor) 생성자와소멸자 객체소멸시자동적으로호출되는함수 소멸자 (cont d) 객체소멸시다양한형태의정리작업필요시... 클래스이름앞에 ~ 가붙은형태의함수 class Point 함수다중정의와디폴트매개변수불가!!! 매개변수와반환되는자료형은선언되지않는다. 소멸자를하나도정의하지않으면, 디폴트 (default) 소멸자가자동삽입된다. int x; int y; ~Point() // default 소멸자 20
복사생성자 복사생성자 자기자신과같은형태의객체를인자로받을수있는생성자 디폴트복사생성자 : 자동으로삽입되는복사생성자 두객체의멤버변수와멤버변수를복사 class Point int int _x; _y; Point() _x = _y = 0; Point(int x, int y = 0) _x = x; _y = y; Point(const Point &p) _x = p.x; _y = p.y; // default 복사생성자 21
복사생성자 얕은복사 (shallow copy) 디폴트복사생성자의문제점 생성자 (cont d) class Person int char _id; *_name; Person a(20115678, 홍길동 ); Person b = a; Person c(a); Person(int id, char *name); ~Person(void); void ShowData(void); // 디폴트복사생성자 Person(const Person &p) _id = p.id; _name = p.name; 22
복사생성자 생성자 (cont d) 프로그램예제 : 디폴트복사생성자의문제점 (1/2) #include <iostream> #include <cstring> using std::cout; using std::endl; class Person int _id; char *_name; Person(int id, char *name); ~Person(void); void ShowData(void); Person::Person(int id, char *name) cout << " 생성자함수호출!!!!" << endl; _id = id; _name = new char[strlen(name)+1]; strcpy(_name, name); Person::~Person(void) cout << " 소멸자함수호출!!!!" << endl; delete []_name; Psrson int _id; char *_name; Person(int, char *); ~Person(); void ShowData(); 23
복사생성자 생성자 (cont d) 프로그램예제 : 디폴트복사생성자의문제점 (2/2) void Person::ShowData(void) cout << " 학번 : " << _id << ", 이름 : " << _name << endl; // 디폴트복사생성자 int main(void) Person(const Person &p) _id = p.id; Person a(20115678, " 홍길동 "); _name = p.name; a.showdata(); Person b = a; // 디폴트복사생성자호출!!! b.showdata(); Person c(a); // 디폴트복사생성자호출!!! c.showdata(); return 0; 24
깊은복사 (Deep copy) 복사생성자 직접복사생성자를제공 생성자 (cont d) 생성자내에서동적할당을하면, 반드시제공되어야한다. class Person int char _id; *_name; Person::Person(const Person &p) _name = new char[strlen(p._name)+1]; strcpy(_name, p._name); Person(int id, char *name); Person(const Person &p); ~Person(void); void ShowData(void); 25
복사생성자 생성자 (cont d) 프로그램예제 : 깊은복사 (1/2) #include <iostream> #include <cstring> using std::cout; Psrson using std::endl; int _id; class Person char *_name; int _id; char *_name; Person(int, char *); Person(int id, char *name); Person(const Person &); Person(const Person &); ~Person(); ~Person(void); void ShowData(void); void ShowData(); Person::Person(int id, char *name) cout << " 생성자함수호출!!!!" << endl; _id = id; _name = new char[strlen(name)+1]; strcpy(_name, name); Person::Person(const Person &p) // 복사생성자 cout << " 복사생성자함수호출!!!!" << endl; _id = p._id; _name = new char[strlen(p._name)+1]; name)+1]; strcpy(_name, p._name); 26
복사생성자 생성자 (cont d) 프로그램예제 : 깊은복사 (2/2) Person::~Person(void) cout << " 소멸자함수호출!!!!" << endl; delete []_name; void Person::ShowData(void) cout << " 학번 : " << _id << ", 이름 : " << _name << endl; int main(void) Person a(20115678, " 홍길동 "); a.showdata(); Person b = a; // 복사생성자호출!!! b.showdata(); Person c(a); // 복사생성자호출!!! c.showdata(); return 0; 27
friend 선언 클래스에대한 friend 선언 다른클래스에서 private 으로선언된영역의접근허용 단, friend 선언은단방향성을지닌다. class Count int i; friend class f_count; class f_count void SetCount(Count &r, int num) r.i = num; 28
friend 선언 (cont d) 전역함수에대한 friend 선언 friend 선언을통해서 private으로선언된멤버변수의접근허용 class Count int i; Count() i = 0; void ShowData(void) cout << i : " << i << endl; friend void SetCount(Count &, int); void SetCount(Count &r, int num) // 전역함수 r.i = num; 29
멤버변수와함수의제한 멤버변수의상수화 생성되는객체마다고유한상수값을지정해주면좋은경우 class Person const int id; char name[12]; Person(int _id, char *_name) id = _id; // error strcpy(name, _name); 멤버이니셜라이저 class Person (member initializer) const int id; char name[12]; Person(int _id, char *_name) : id(_id) strcpy(name, _name); 30
멤버변수와함수의제한 (cont d) const 멤버함수 상수화된멤버함수는멤버변수의값변경불가 class Count int i; Count() i = 0; void ShowData(void) const i++; // error cout << i : " << i << endl; 31
멤버변수와함수의제한 (cont d) static 멤버변수 main 함수호출되기전에메모리공간을할당받고초기화 객체의멤버로존재하지않는다 ( 클래스내에서접근할수있는권한부여 ). class Count static int i; int Count::i = 1; int main() cout << Count::i << endl; Count::i++; cout << Count::i << endl; return 0; 32
객체의포인터 클래스와포인터, 배열 객체를가리키는 ( 참조하는 ) 용도로사용되는포인터 class Point int x; int y; void OUTPUT(void) cout << "x : " << x << ", y : " << y << endl; int main(void) Point a; Point *p = &a; a.output(); (*p).output(); p->output(); return 0; int x; int y; void OUTPUT(); Point 33
클래스와포인터, 배열 (cont d) 자기참조포인터 this는자기자신을가리키는 ( 참조하는 ) 용도로사용되는포인터 멤버함수내에서 this 라는이름의포인터를사용 class Point int x; int y; Point *GetThis(void) return this; int x; int y; Point *GetThis(); Point int main() Point *p = new Point(); // Point *p = new Point; cout << "p : " << p << endl; cout << "this : " << p->getthis() << endl; return 0; 34
클래스와포인터, 배열 (cont d) 자기참조포인터 (cont d) class Point int x; int y; Point() x = y = 0; Point(int x, int y = 0) this->x = x; this->y = y; Point(const Point &p) this->x = p.x; this->y = p.y; this 포인터로멤버변수의이름충돌해결!!! Point int x; int y; Poin(); Point(int, int = 0); Point(const Point &); 35
클래스와포인터, 배열 (cont d) 객체의배열 클래스도자료형의한종류기때문에배열을생성할수있다. 객체의배열을정의할때각객체들은디폴트생성자로초기화된다. class Point int x; int y; Point() x = y = 0; Point(int x, int y = 0) this->x = x; this->y = y; Point(const Point &p) this->x = p.x; this->y = p.y; Point arr[0]; arr[1]; arr[2]; arr[3]; 36
클래스와포인터, 배열 (cont d) 객체의포인터배열 객체를가리키는 ( 참조하는 ) 용도로사용되는포인터배열 class Point Point *arr[3]; int x; int y; Point() x = y = 0; Point(int x, int y = 0) this->x = x; this->y = y; Point(const Point &p) this->x = p.x; this->y = p.y; arr[0] = new Point(); arr[1] = new Point(10, 20); arr[2] = new Point(*arr[1]); 37
클래스와포인터, 배열 (cont d) 프로그램예제 : 객체의포인터배열 (1/2) #include <iostream> using std::cin; Point using std::cout; int x; using std::endl; int y; class Point Poin(); int x; Point(int, int = 0); int y; Point(const Point &); Point(); void ShowData(); Point(int, int = 0); Point(const Point &); void ShowData(void); Point::Point() x = y = 0; Point::Point(int x, int y) this->x = x; this->y = y; Point::Point(const Point &p) this->x = p.x; this->y = p.y; 38
클래스와포인터, 배열 (cont d) 프로그램예제 : 객체의포인터배열 (2/2) void Point::ShowData(void) cout << "x : " << x << ", y : " << y << endl; int main(void) int i; Point *arr[3]; arr[0] = new Point(); arr[1] = new Point(10, 20); arr[2] = new Point(*arr[1]); for(i=0; i<3; i++) arr[i]->showdata(); for(i=0; i<3; i++) delete arr[i]; return 0; 39
참고문헌 [1] 윤성우, 열혈강의 C++ 프로그래밍, 프리렉, 2007. [2] 이현창, 뇌를자극하는 C++ 프로그래밍, 한빛미디어, 2008. [3] H.M. HM Deitel, P. J. Deitel, C++ C HOW TO PROGRAM : 6th Edition, Prentice Hall, 2009. [4] Wikipedie, http://www.wikipedia.org/. 이강의자료는저작권법에따라보호받는저작물이므로무단전제와무단복제를금지하며, 내용의전부또는일부를이용하려면반드시저작권자의서면동의를받아야합니다. Copyright Clickseo.com. All rights reserved. 40