제5장 생성자와 접근제어 객체 지향 기법을 이해한다. 클래스를 작성할 수 있다. 클래스에서 객체를 생성할 수 있다. 생성자를 이용하여 객체를 초기화할 수 있다. 접근자와 설정자를 사용할 수 있다.
이번 장에서 만들어볼 프로그램
생성자 생성자(constructor)는 초기화를 담당하는 함수
생성자가 필요한 이유 #include <iostream> using namespace std; class Time { public: int hour; // 시를 나타낸다. 0-23가 가능하다. int minute; // 분을 나타낸다. 0-59가 가능하다. void print() { cout << hour << ":" << minute << endl; } }; Time a; // 객체 a를 생성한다. a.hour = 26; a.minute = 70;
생성자의 예 class Time { public: int hour; // 0-23 int minute; // 0-59 Time(int h, int m) { hour = h; minute = m; } void print() { cout << hour << ":" << minute << endl; };
생성자를 호출하는 방법 Time a; // ① 오류이다! 초기화값이 없다! Time b(10, 25); // ② OK 하지만 예전의 방법이다. Time c { 10, 25 }; // ③ OK 최신의 방법이다. Time d = { 10, 25 }; // ④ OK 하지만 간결하지 않다.
생성자의 중복 정의 #include <iostream> using namespace std; class Time { public: int hour; // 0-23 int minute; // 0-59 Time() { hour = 0; minute = 0; } Time(int h, int m) { hour = h; minute = m; void print() { cout << hour << ":" << minute << endl; };
디폴트 생성자 #include <iostream> using namespace std; class Time { public: int hour; // 0-23 int minute; // 0-59 Time(int h=0, int m=0) { hour = h; minute = m; } void print() { cout << hour << ":" << minute << endl; };
디폴트 생성자 int main() { Time a; // OK Time b{ 10, 25 }; // OK a.print(); b.print(); return 0; }
멤버 초기화 리스트 Time(int h, int m) : hour{h}, minute{m} { }
소멸자
소멸자 #include <string.h> class MyString { private: char *s; int size; public: MyString(char *c) { size = strlen(c)+1; s = new char[size]; strcpy(s, c); } ~MyString() { delete[] s; }; int main() { MyString str("abcdefghijk");
Lab: Rect 클래스 사각형을 나타내는 Rectangle 클래스에 생성자를 추가해 보자.
solution #include <iostream> using namespace std; class Rectangle { int width, height; public: Rectangle(int w, int h); int calcArea(); }; Rectangle::Rectangle(int w, int h) { width = w; height = h; } int Rectangle::calcArea() return width*height;
solution int main() { Rectangle r{ 3, 4 }; cout << "사각형의 넓이 : " << r.calcArea() << '\n'; return 0; }
Lab: Circle 클래스 원을 나타내는 Circle 클래스를 작성하여 보았다. 원은 중 심점과 반지름과 색상으로 표현된다. 약 10개의 Circle 객 체를 생성하면서 랜덤한 위치와 랜덤한 반지름으로 화면 에 원을 그려보자. 원의 중심점과 반지름은 생성자를 호 출하여 설정하라
solution #include <windows.h> #include <iostream> using namespace std; class Circle { int x, y, radius; string color; public: Circle(int xval = 0, int yval = 0, int r = 0, string c = ""); double calcArea() { return radius*radius*3.14; } void draw(); }; Circle::Circle(int xval, int yval, int r, string c) x = xval; y = yval; radius = r; color = c; }
예제 class Time { private: // 이후에 선언되는 멤버는 모두 전용 멤버가 된다. int hour; // 0-23 int minute; // 0-59 public: Time(int h, int m); void inc_hour(); void print(); }; Time::Time(int h, int m) { hour = h; minute = m; } void Time::inc_hour() { ++hour; if (hour > 23) hour = 0;
예제 Time a { 24, 59 }; ++a.hour; // 이제는 오류가 발생한다!!
접근제어
접근자와 설정자
예제 #include <iostream> using namespace std; class Time { public: Time(int h, int m); void inc_hour(); void print(); int getHour() { return hour; } int getMinute() { return minute; } void setHour(int h) { hour = h; } void setMinute(int m) { minute = m; } private: int hour; // 0-23 int minute; // 0-59 };
예제 int main() { Time a{ 0, 0 }; a.setHour(6); a.setMinute(30); a.print(); return 0; }
Lab: 원들의 경주 지금까지 학습한 내용을 바탕으로 “원들의 경주“ 게임을 다시 작성하여 보자. 두 개의 원을 생성한 후에 난수를 발 생하여 원들을 움직인다.
Solution #include <iostream> #include <windows.h> using namespace std; class Circle { public: Circle(int xval, int yval, int r); void draw(); void move(); private: int x, y, radius; }; Circle::Circle(int xval, int yval, int r) : x{ xval }, y{ yval }, radius{ r } { }
Solution void Circle::draw() { HDC hdc = GetWindowDC(GetForegroundWindow()); Ellipse(hdc, x - radius, y - radius, x + radius, y + radius); } void Circle::move() { x += rand() % 50; int main() { Circle c1{ 100, 100, 50 }; Circle c2{ 100, 200, 40 }; for (int i = 0; i < 20; i++) { c1.move(); c1.draw(); c2.move(); c2.draw(); Sleep(1000); return 0;
객체와 함수 객체가 함수의 매개 변수로 전달되는 경우 객체의 참조자가 함수의 매개 변수로 전달되는 경우 함수가 객체를 반환하는 경우
객체가 함수의 매개 변수로 전달되는 경우 값을 전달한다. 어떤 피자 체인점에서 미디엄 크기의 피자를 주문하면 무 조건 라지 피자로 변경해준다고 하자. 다음과 같이 프로 그램을 작성하면 피자의 크기가 커질까?
#include <iostream> using namespace std; class Pizza { public: Pizza(int s) : size(s) { } int size; // 단위: 인치 }; void makeDouble(Pizza p){ p.size *= 2; } int main(){ Pizza pizza(10); makeDouble(pizza); cout << pizza.size << "인치 피자" << endl; return 0;
실행결과
객체의 참조자가 함수의 매개 변수로 전달되는 경우 #include <iostream> using namespace std; class Pizza { public: Pizza(int s) : size(s) { } int size; // 단위: 인치 }; void makeDouble(Pizza& p) { p.size *= 2; } int main() { Pizza pizza(10); makeDouble(pizza); cout << pizza.size << "인치 피자" << endl; return 0;
실행결과
함수가 객체를 반환하는 경우 함수가 객체를 반환할 때도 객체의 내용이 복사될 뿐 원 본이 전달되지 않는다.
예제 #include <iostream> using namespace std; class Pizza { public: Pizza(int s) : size(s) { } int size; // 단위: 인치 }; Pizza createPizza() { Pizza p(10); return p; } int main() { Pizza pizza = createPizza(); cout << pizza.size << "인치 피자" << endl; return 0;
실행결과
Q & A