4 장클래스와객체 클래스와객체 public과 private 구조체와클래스객체의생성과생성자객체의소멸과소멸자생성자와소멸자의호출순서디폴트생성자와디폴트소멸자멤버초기화멤버함수의외부정의멤버함수의인라인함수선언 C++ 프로그래밍입문
1. 클래스와객체 추상데이터형 : 속성 (attribute) + 메서드 (method) 예 : 자동차의속성과메서드 C++ : 주로 class 로표현 구조체, 공용체, typedef 역시추상데이터형에포함됨 à 사용자정의형 (user-defined type) 으로불림 4 장클래스와객체 1
1. 클래스와객체 타입 à 변수, 클래스 à 객체 객체선언방법 : 기본적으로는변수생성과동일 Car MyCar, YourCar; MyCar. 색상 = Red; 예 : Car 클래스구현 속성 : 멤버변수 메서드 : 멤버함수 class Car int m_color; int m_cc; int m_speed; // 색상 // 배기량 // 속도 void Accelerate() m_speed++; // 가속 void Stop() // 멈춤 void TurnOn() // 시동켜기 Car MyCar1, MyCar2; // 객체생성 MyCar1.m_speed = 0; MyCar2.m_CC = 1000; MyCar1.Accelerate(); // 멤버함수호출 4 장클래스와객체 2
1. 클래스와객체 Car 클래스예제에서객체들의메모리구조 ( 개념적표현 ) 각객체별로별도의변수와함수생성 class Car int m_color; // 색상 int m_cc; // 배기량 int m_speed; // 속도 void Accelerate() m_speed++; // 가속 void Stop() // 멈춤 void TurnOn() // 시동켜기 Car MyCar1, MyCar2; MyCar1.m_speed = 0; MyCar2.m_CC = 1000; MyCar1.Accelerate(); // 객체생성 // 멤버함수호출 MyCar1.Accelerate() à MyCar1 의멤버변수 m_speed 값증가 실제로는객체별로멤버변수가따로생성되지만멤버함 수는단하나만생성됨 à 5.3 절 4 장클래스와객체 3
2. public 과 private Car 클래스예제의컴파일 à 에러발생 정보은닉 : 클래스내부데이터에대한접근제어 public 멤버 : 외부접근가능 private 멤버 : 외부접근금지 à 데이터보호 예 : Car 클래스 private 영역 public 영역 private, public 이여러번나올수있음 private 이후 : private 영역 public 이후 : public 영역 private 멤버에대한외부접근불가 주로멤버변수는 private 멤버로, 멤버함수는 public 멤버로. 반드시그럴필요는없음. class Car int m_color; int m_cc; int m_speed; 클래스시작부에 private, public 이명시되어있지않으면 à 디폴트로 private 으로인식 // 색상 // 배기량 // 속도 void Accelerate() m_speed++; // 가속 void Stop() // 멈춤 void TurnOn() // 시동켜기 private 멤버에대한 내부접근허용 Car MyCar1, MyCar2; //MyCar1.m_speed = 0; //MyCar2.m_CC = 1000; MyCar1.Accelerate(); 4 장클래스와객체 4
3. 구조체와클래스 예 : 평면상의한점을나타내는 Point 구조체만들기 struct Point // 평면상의좌표 (x, y) 를나타내는 구조체 int x; int y; Point P1; P1.x = 3; P1.y = 4; 구조체는디폴트로외부접근허용 (public) cout << P1.x << " " << P1.y << endl; C++ 의구조체는클래스와 99.8% 동일 멤버변수와멤버함수포함가능 private, public 영역지정가능 4 장클래스와객체 5
3. 구조체와클래스 예 : 구조체를클래스처럼사용하기 struct Point int x; int y; void SetXY(int a, int b) x = a; y = b; void Print() cout << "(" << x << ", " << y << ")" << endl; Point P1; P1.SetXY(3, 4); P1.Print(); 구조체와클래스의차이점 2 가지 1. private, public 지정을하지않을경우 - 클래스 : 디폴트로 private - 구조체 : 디폴트로 public 2. 상속 : 8 장 구조체와클래스중어떤것을쓸것인가? à 개인적취향에따라선택 - public 멤버변수만을포함 à 구조체 - 함수포함또는 private 멤버포함 à 클래스 4 장클래스와객체 6
4. 객체의생성과생성자 변수의초기화 : 다음 2 가지의차이점은? int a; a = 100; int a = 100; 구조체변수의초기화 struct Point int x; int y; 쓰레기값으로초기화한후대입문에의해 100 으로변경 메모리생성과동시에 100 으로초기화 Point P1 = 3, 4 // 구조체변수의초기화 4 장클래스와객체 7
4. 객체의생성과생성자 클래스객체의초기화 : 다음프로그램의문제점은? class CPoint int x; int y; CPoint P1 = 3, 4 // X, 멤버변수 x 가 private 이므로직접접근불가능 클래스객체생성과동시에멤버변수의값을초기화하는방법 à 생성자 4 장클래스와객체 8
4. 객체의생성과생성자 생성자 일종의멤버함수. 객체가생성되면반드시생성자가호출됨 생성자에대한제약사항 생성자이름은클래스이름과같다. 반환형이없으며어떤것도반환하지않는다. 매개변수는일반함수와마찬가지로자유롭게줄수있다. 생성자오버로딩을통해다양한생성자를만들수있다. 디폴트매개변수를사용할수있다. 생성자의예 class CPoint int x; int y; CPoint(int a, int b) x = a; y = b; // 생성자 void Print() cout << "(" << x << ", " << y << ")" << endl; 4 장클래스와객체 9
4. 객체의생성과생성자 생성자의호출 객체생성시매개변수전달 CPoint P1 = CPoint(3, 4); CPoint P2(5, 6); P1.Print(); P2.Print(); 둘다객체생성첫번째는대입이아님! 주로두번째스타일사용. 4 장클래스와객체 10
4. 객체의생성과생성자 생성자오버로딩 : 여러개의생성자작성가능 class CPoint int x; int y; CPoint(int a, int b) x = a; y = b; // 생성자1, 2개의매개변수 CPoint(int a) x = a; y = 0; // 생성자2, 1개의매개변수 void Print() cout << "(" << x << ", " << y << ")" << endl; CPoint P1(3, 4); CPoint P2(5); CPoint P3 = 6; P1.Print(); P2.Print(); P3.Print(); // 생성자1 사용 // 생성자2 사용 // 6 => CPoint(6) 변환, 변환시생성자2 사용 생성자의매개변수가하나일경우이와같은사용가능 à 묵시적형변환을통해수행됨 4 장클래스와객체 11
4. 객체의생성과생성자 디폴트매개변수사용가능 class CPoint int x; int y; CPoint(int a, int b = 0) x = a; y = b; // 생성자 void Print() cout << "(" << x << ", " << y << ")" << endl; CPoint P1(3, 4); CPoint P2(5); CPoint P3 = 6; P1.Print(); P2.Print(); P3.Print(); 4 장클래스와객체 12
5. 객체의소멸과소멸자 객체생성 à 생성자호출, 객체소멸 à 소멸자호출 객체가소멸되는시점 (= 변수소멸시점 ) 1 지역변수 : 해당함수의수행이완료되고반환될때 2 전역변수 : 프로그램이종료될때 소멸자에대한제약사항 1 소멸자이름은클래스이름과동일하다. 단, 생성자와의구별을위해이 름앞에 ~ 문자가붙는다. 2 반환형및반환값이없다. 3 매개변수가존재하지않는다. 따라서단하나의소멸자만존재할수있다. class CPoint int x, int y; CPoint(int a, int b) x = a; y = b; // 생성자 ~CPoint() cout << " 소멸자 " << endl; // 소멸자 void Print() cout << "(" << x << ", " << y << ")" << endl; 4 장클래스와객체 13
5. 객체의소멸과소멸자 소멸자가필요한예 : 메모리를동적으로생성하여사용하는경우 class CArray int count; int *x; 객체생성시 new 를통해배열을생성하였으므로어딘가에서 delete [] 를수행해야함. CArray(int a) count = a; x = new int[count]; void Delete() delete [] x; void Print() for (int i = 0; i < count; i++) cout << x[i] << endl; CArray ary(5); ary.print(); ary.delete(); // 생성자 // 메모리해제 다음과같은소멸자를추가한다면더이상 Delete 함수와 Delete 함수호출이필요없음 ~CArray() delete [] x; // 소멸자, 메모리해제 4 장클래스와객체 14
6. 생성자와소멸자의호출순서 생성자 : 객체생성순, 소멸자 : 객체생성의역순 class CPoint int x; int y; 멤버함수내에서멤버변수뿐만아니라다른멤버함수호출가능! CPoint(int a, int b) x = a; y = b; cout << " 생성자 : "; Print(); ~CPoint() cout << " 소멸자 : "; Print(); void Print() cout << "(" << x << ", " << y << ")" << endl; CPoint P1(1, 1); CPoint P2(2, 2); CPoint P3(3, 3); CPoint P4(4, 4); // 전역객체 // 전역객체 // 지역객체 // 지역객체 4 장클래스와객체 15
7. 디폴트생성자와디폴트소멸자 다음프로그램을수행시켜보라. class CPoint int x, y; void SetXY(int a, int b) x = a; y = b; void Print() cout << "(" << x << ", " << y << ")" << endl; CPoint P1; P1.SetXY(3, 4); P1.Print(); 객체생성 à 생성자호출 à 생성자는어디에? 객체소멸 à 소멸자호출 à 소멸자는어디에? 4 장클래스와객체 16
7. 디폴트생성자와디폴트소멸자 디폴트생성자와디폴트소멸자 생성자를만들지않을경우디폴트생성자가동작함 CPoint() // 매개변수없음. 특별히하는일은없음 소멸자를만들지않을경우디폴트소멸자가동작함 ~CPoint() // 특별히하는일은없음 생성자를 1 개이상명시적으로추가하면디폴트생성자는사라짐 소멸자를명시적으로추가하면디폴트소멸자는사라짐 다음프로그램의문제점은? class CPoint int x; int y; 생성자는어디에? CPoint P1(3, 4); CPoint P2; P1.Print(); P2.Print(); CPoint(int a, int b) x = a; y = b; // 생성자 void Print() cout << "(" << x << ", " << y << ")" << endl; 4 장클래스와객체 17
7. 디폴트생성자와디폴트소멸자 다음코드의의미는? CPoint P1(); // CPoint 객체 P1 생성? No! 이것은매개변수가없고 CPoint 객체를반환하는 P1 함수의프로토타입을의미함 CPoint P1(void); 비교 : int func(void); 객체생성시매개변수가없을경우에는항상다음과같이선언 CPoint P1; 4 장클래스와객체 18
8. 멤버초기화 객체생성시멤버변수초기화방법 생성자내에서대입문사용 ( 기존방법 ) 멤버초기화구문사용 : 멤버변수메모리생성과동시에초기화! class CPoint int x; int y; 멤버변수의초기화순서는선언된순서를따름생성자에서기술된순을따르지않음 ( 비교 ) int a; a = 5; int a = 5; CPoint(int a, int b) : x(a), y(b) // 멤버초기화구문 // CPoint(int a, int b) x = a; y = b; void Print() cout << "(" << x << ", " << y << ")" << endl; CPoint P1(3, 4); P1.Print(); 생성자작성시멤버초기화를사용할것인가? 생성자내에서대입문을사용할것인가? à 차이점만알고있다면어느것을사용해도무방 à 단, 반드시멤버초기화를사용해야하는상황이있음 à 8.4 절, 9.8 절 4 장클래스와객체 19
9. 멤버함수의외부정의 멤버함수정의방법 내부정의 : 클래스선언내부에함수몸체작성 외부정의 : 클래스선언내부에함수프로토타입만선언, 함수몸체는클 래스외부에작성 class CPoint int x, y; CPoint(int a, int b); void Move(int a, int b); void Print(); CPoint::CPoint(int a, int b) : x(a), y(b) // 생성자의외부정의 void CPoint::Move(int a, int b) // 멤버함수의외부정의 x = x + a; y = y + b; 반환형클래스명 :: 함수명 ( ) void CPoint::Print() // 멤버함수의외부정의 cout << "(" << x << ", " << y << ")" << endl; CPoint P1(3, 4); P1.Move(5, 6); P1.Print(); 4 장클래스와객체 20
10. 멤버함수의인라인함수선언 멤버함수를내부정의로구현하는경우 자동으로인라인함수로인식 à 자동인라인 외부정의시인라인함수로선언하는방법 외부정의시 inline 키워드만추가하면됨 class CPoint int x; int y; CPoint(int a, int b) : x(a), y(b) inline void Print(); inline void CPoint::Print() // 인라인함수선언 cout << "(" << x << ", " << y << ")" << endl; 4 장클래스와객체 21