차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판 이전 판
activity:public:2021:cpp:210720 [2021/07/21 03:45:36] – [예제] yhy01625activity:public:2021:cpp:210720 [2021/07/23 22:05:46] (현재) – [C++ 스터디 #11: 클래스(1)] bkparks12
줄 1: 줄 1:
 +======C++ 스터디 #11: 클래스(1)======
  
 +| 시간 | 2021년 7월 20일 화요일 20:00 ~ 22:00 |
 +| 장소 | ZOOM |
 +| 참가자 | - |
 +
 +{{youtube>tGrFCdna54o?medium}}
 +=====1. 객체 지향 프로그래밍=====
 +====1.1. 개요====
 +현재 많이 사용되는 프로그래밍 기법은 절차 지향 프로그래밍과 객체 지향 프로그래밍으로 나눌 수 있습니다.
 +
 +\\
 +{{:activity:public:2021:cpp:ㅈㅊㅈㅎ.png?200|}}
 +{{:activity:public:2021:cpp:ㄱㅊㅈㅎ.png?200|}}
 +
 +\\
 +**절차 지향 프로그래밍(procedural programming)**에서 전체 프로그램은 함수들의 집합으로 이루어집니다. 이런 설계 방법은 하향식 설계라고도 불립니다.\\
 +하지만 데이터가 함수와 분리되기 때문에 프로그래머들은 함수 작성에만 신경을 쓰게 되는 단점이 있습니다.\\
 +\\
 +이런 문제점을 해결하기 위해 등장한 것이 **객체 지향 프로그래밍(object-oriented programming)**입니다.\\
 +객체 지향 프로그래밍은 데이터와 함수를 하나의 덩어리인 객체로 묶어서 생각하는 방법입니다.\\
 +이렇게 묶는 것을 **캡슐화(encapsulation)**라고 부릅니다.
 +
 +
 +====1.2. 객체의 구성====
 +객체는 상태와 동작을 가지고 있습니다. 객체의 **상태(state)**는 객체의 속성입니다.\\
 +예를 들어 자동차 객체의 경우 속성은 차종, 색상, 기어, 속도, 배기량, 주행 거리, 연비 등을 생각할 수 있습니다.\\
 +객체의 **동작(behavior)**은 객체가 취할 수 있는 동작입니다.\\
 +자동차를 예로 들면 출발하기, 멈추기, 가속하기, 방향 전환하기 등이 여기에 해당됩니다.
 +
 +객체의 상태와 동작은 프로그램에서 변수와 함수로 표현할 수 있습니다.\\
 +즉 객체는 변수와 함수로 이루어져 있는 코드의 묶음이라 할 수 있습니다.
 +\\
 +  ***멤버 변수 :** 객체 안의 변수에는 객체의 상태를 저장합니다. 객체 안에 포함된 변수를 일반적인 변수와 구별하기 위하여 특별히 **멤버 변수 또는 필드(field)**라고 합니다.
 +  ***멤버 함수 :** 객체 안의 함수는 특정한 동작을 수행합니다. 일반적인 함수와 구별하기 위해서 객체 안의 함수를 **멤버 함수 또는 메소드(method)**라고 합니다.
 +
 +====1.3. 캡슐화====
 +
 +새로운 프로그램을 개발할 때 기존에 작성된 코드를 재사용할 수 있다면 편리할 것입니다.\\
 +관련 데이터와 알고리즘이 하나의 묶음으로 정리되어 있고, 객체 지향 프로그래밍에서는 이를 캡슐화라고 합니다.\\
 +객체가 하나의 캡슐에 해당하고, 클래스의 멤버 변수가 데이터와, 멤버 함수는 알고리즘에 각각 해당합니다.\\
 +\\
 +**캡슐화의 목적 1. 관련 데이터와 알고리즘 묶기**\\
 +서로 관련되어 있는 데이터와 알고리즘이 묶여 있으면 사용하기 매우 편리합니다.\\
 +캡슐로 된 약처럼, 캡슐로 감싸져 있지 않으면 안의 내용물들이 흩어지게 되고 복용이 힘들 것입니다.\\
 +\\
 +**캡슐화의 목적 2. 정보 은닉: 접근 가능한 것과 접근해서는 안되는 것 분리**\\
 +외부에서 객체의 세부 사항을 너무 많이 알아도 문제가 될 수 있습니다.\\
 +어떤 사람이 TV 채널을 돌리거나 음량을 바꿀 때 리모콘을 사용하지 않고 내부 회로를 마구 조작하면서 사용하다가, 중요한 부분을 잘못 건드리게 되면 TV가 고장이 날 수 있을 뿐더러 고치기도 쉽지 않습니다.\\
 +TV 제조사가 안전하게 TV를 사용할 수 있게 리모콘을 제공한 것처럼, 프로그래밍에서도 객체를 사용할 때 접근 가능한 것과 접근해서는 안되는 것을 분리합니다.\\
 +=====2. 클래스=====
 +
 +====2.1. 클래스의 역할====
 +
 +자동차 객체의 경우 같은 설계도에 의해 각각의 자동차가 만들어집니다. 객체 지향 소프트웨어에서도 같은 객체들이 여러 개 필요한 경우가 있습니다.\\
 +이러한 객체들은 모두 하나의 설계도로 만들어집니다. 바로 이 설계도를 **클래스(class)**라고 합니다.\\
 +다시 말하면 클래스란 어떤 종류의 모든 객체에게 공통인 멤버 변수와 멤버 함수를 정의하는 형틀 또는 청사진이라고 할 수 있습니다.\\
 +객체 지향 프로그래밍에서는 클래스로부터 만들어지는 객체를 그 클래스의 **인스턴스(instance)**라고 합니다.
 +
 +객체가 생성될 때마다 각 객체에 필요한 기억 공간이 할당됩니다. 같은 설계도로 만들어진 자동차라고 해도 각 자동차의 속도, 주행 거리, 기어 등의 상태는 다릅니다.\\
 +따라서 같은 클래스로 만들어진 인스턴스라고 해도 각기 다른 상태 값을 가질 수 있습니다. 따라서 이들 상태 값을 저장할 공간이 객체마다 필요합니다. 즉 객체마다 멤버 변수의 값은 달라집니다.
 +
 +멤버 함수의 경우는 약간 다릅니다. 자동차를 예로 들면 전조등을 켜는 방법은 같은 설계도로 만든 자동차이면 모두 동일합니다.\\
 +따라서 객체의 멤버 함수들은 객체마다 저장되는 것이 아니라 하나의 멤버 함수를 공유합니다.\\
 +정리하자면 같은 클래스의 인스턴스들은 멤버 함수는 공유하지만 멤버 변수는 각각 가지고 있다고 말할 수 있습니다.
 +
 +====2.2. 클래스 작성====
 +클래스는 다음과 같이 정의됩니다.
 +
 +  class 클래스이름 {
 +      자료형 멤버변수1;
 +      자료형 멤버변수2;
 +    
 +      반환형 멤버함수1();
 +      반환형 멤버함수2();
 +  };
 +\\
 +간단한 예시를 작성하면 다음과 같습니다.
 +<sxh cpp>
 +class Circle {
 +public:
 +    int radius;
 +    string color;
 +    
 +    double calcArea() {
 +        return 3.14*radius*radius;
 +    }
 +};
 +</sxh>
 +일반적으로 클래스 이름은 명사로 하며, 첫 글자는 대문자로 합니다. 위 예시에서 클래스의 이름은 Circle입니다.\\
 +이어서 등장하는 키워드 public은 외부에서 멤버들을 자유롭게 사용할 수 있음을 의미합니다.\\
 +Circle 클래스 안에는 원의 반지름을 나타내는 radius 변수와 원의 색상을 나타내는 color 변수를 선언하였고 멤버 함수로는 원의 반지름을 계산하여 반환하는 calcArea() 함수를 정의했습니다.\\
 +클래스의 정의가 끝나면 반드시 ;을 붙어야 합니다.
 +
 +====2.3. 객체 생성====
 +클래스를 선언하였다고 해서 객체가 생성된 것은 아닙니다. 클래스의 정의는 객체를 찍어내는 틀을 만든 것에 불과합니다.\\
 +틀을 사용하여 객체를 생성해야 객체를 사용할 수 있습니다.
 +  Circle obj;
 +위의 문장이 실행되면 obj라는 객체가 생성되게 됩니다. 이처럼 실제로 생성된 객체를 클래스의 인스턴스라고 부릅니다.\\
 +Circle이라는 클래스 이름은 자료형의 이름으로 생각할 수 있습니다. obj는 객체의 이름이 됩니다.
 +
 +====2.4. 객체의 멤버 접근====
 +객체 안에 정의된 멤버 변수와 멤버 함수를 사용하려면 도트(.)연산자를 사용해야 합니다.\\
 +예를 들어 obj 객체의 변수 radius에 값을 대입하려면 다음과 같이 해야 합니다.
 +  obj.radius = 3;
 +하나의 클래스에서 많은 객체가 생성될 수 있기 때문에 어떤 객체의 어떤 멤버인지를 적어주는 것입니다.
 +  obj.calcArea();
 +위와 같이 도트 연산자를 이용하여 멤버 함수도 호출할 수 있습니다.
 +
 +====2.5. 예제====
 +사각형을 클래스 Rectangle로 표현하세요. width, height를 멤버 변수로 가지고 사각형의 면적을 계산하는 calcArea()를 멤버 함수로 가져야 합니다.\\
 +그리고 클래스 Rectangle로 obj1, obj2라는 이름의 두 개의 객체를 생성하고 각 객체의 면적을 출력하는 프로그램을 작성하세요.
 +
 +
 +=====3. 멤버 함수 중복 정의=====
 +<sxh cpp>
 +#include <iostream>
 +#include <string>
 +using namespace std;
 +
 +class PrintData {
 +public:
 +    void print(int i) {cout << i << endl;}
 +    void print(double f) {cout << f << endl;}
 +    void print(string s = "No Data!") {cout << s << endl;}
 +};
 +
 +int main() {
 +    PrintData obj;
 +    
 +    obj.print(1);
 +    obj.print(3.14);
 +    obj.print("KAsimov");
 +    obj.print();
 +    
 +    return 0;
 +}
 +</sxh>
 +
 +위의 코드에서 멤버 함수 print()는 정수, 실수, 문자열에 대하여 중복 정의되어 있습니다.\\
 +따라서 어떤 자료형의 데이터든지 출력할 수 있습니다. 문자열을 출력하는 print()는 매개 변수가 주어지지 않으면 문자열 "No Data!"를 출력합니다.\\
 +
 +출력 예시:\\
 +{{:activity:public:2021:cpp:캡처111111.png?200|}}
 +=====4. 클래스의 인터페이스와 구현의 분리=====
 +만약 멤버 함수가 매우 복잡해서 100줄이 넘으면 클래스의 정의가 어디서 시작해서 어디서 끝나는지를 분간하기 힘들 것입니다.\\
 +이런 경우에는 클래스 외부에 멤버 함수를 정의해야 합니다.\\
 +<sxh cpp>
 +#include <iostream>
 +#include <string>
 +using namespace std;
 +
 +class Circle {
 +public:
 +    double calcArea();
 +    
 +    int radius;
 +    string color;
 +}
 +
 +double Circle::calcArea() {
 +    return 3.14*radius*radius;
 +}
 +
 +int main() {
 +    Circle obj;
 +    obj.radius = 10;
 +    
 +    cout << obj.calcArea() << endl;
 +    
 +    return 0;
 +}
 +</sxh>\\
 +클래스 외부에서 calcArea() 함수를 정의할 때 함수 이름 앞에 클래스 이름인 Circle과 ::연산자를 붙인 것을 볼 수 있습니다.\\
 +::연산자는 이름공간(name space)를 지정하는 연산자입니다.
 +
 +=====5. 생성자=====
 +====5.1. 생성자 함수====
 +변수를 사용하기 위해서는 초기화를 해주어야 한다.\\
 +객체도 이와 마찬가지로 생성한 후 초기화를 해야 사용할 수 있다.\\
 +C++에서는 초기화를 담당하는 생성자 함수가 존재한다. 이를 사용하면 객체의 생성과 동시에 초기화를 할 수 있다.\\
 +\\
 +직사각형을 나타내는 클래스 Rectangle을 다음과 같이 정의하자.
 +<sxh cpp>
 +#include <iostream>
 +using namespace std;
 +
 +class Rectangle {
 +private:
 +    int width, height;
 +public:
 +    int calcArea() {
 +        return width * height;
 +    }
 +};
 +</sxh>
 +\\
 +클래스 Rectangle의 객체를 생성하고 변수에 여러 값들을 저장해보자.
 +
 +<sxh cpp>
 +int main() {
 +    Rectangle r;  // 객체 r을 생성한다.
 +
 +    r.width = 4;  // 객체 r의 너비를 4, 높이를 3으로 설정한다.
 +    r.height = 3;
 +
 +    return 0;
 +}
 +</sxh>
 +\\
 +하지만 깜빡하고 객체를 초기화하지 않는다면 문제가 발생할 것이다.
 +
 +<sxh cpp>
 +int main() {
 +    Rectangle r;
 +
 +    cout << r.calcArea();  // 객체를 초기화하지 않아 쓰레기 값이 출력된다.
 +
 +    return 0;
 +}
 +</sxh>
 +
 +혹은, 멤버 변수가 private이라면 변수에 직접 접근할 수 없어 아까와 같은 방법으로는 값을 저장할 수 없다.\\
 +이때는 값을 저장할 수 있는 public인 멤버 함수를 만들어 사용해야 한다.\\
 +따라서 객체를 생성할 때 자동으로 객체를 초기화할 수 있다면 매우 편리할 것이다.\\
 +이를 생성자 함수라고 한다.
 +
 +<sxh cpp>
 +class Rectangle {
 +private:
 +    int width, height;
 +public:
 +    Rectangle(int w, int h) {
 +        width = w;
 +        height = h;
 +    }
 +    int calcArea() {
 +        return width * height;
 +    }
 +};
 +</sxh>
 +
 +생성자는 클래스 이름과 똑같은 멤버 함수이고 반환 형식은 따로 존재하지 않는다.
 +
 +<sxh cpp>
 +    Rectangle a;  // 오류! 초기화값 없음
 +    Rectangle b(4, 3);  // OK. 직접 초기화, 예전 방법, 하지만 함수 선언과 혼동할 수 있음
 +    Rectangle c {4, 3};  // OK. 유니폼 초기화, 최신 방법.
 +    Rectangle d = {4, 3};  // OK. 약간은 간결하지 않음
 +</sxh>
 +
 +생성자를 사용하는 전체 코드는 이렇다.
 +
 +<sxh cpp>
 +#include <iostream>
 +using namespace std;
 +
 +class Rectangle {
 +private:
 +    int width, height;
 +public:
 +    Rectangle(int w, int h) {
 +        width = w;
 +        height = h;
 +    }
 +    int calcArea() {
 +        return width * height;
 +    }
 +};
 +
 +int main() {
 +    Rectangle r {4, 3};
 +    cout << r.calcArea();  // 12
 +
 +    return 0;
 +}
 +</sxh>
 +\\
 +====5.2. 생성자 중복 정의====
 +
 +생성자도 멤버 함수의 일종이라고 생각할 수 있고, 따라서 생성자도 함수 오버로딩처럼 중복 정의가 가능하다.
 +
 +다음은 매개 변수가 없는 생성자와 매개 변수가 있는 생성자를 동시에 정의한 것이다.
 +
 +<sxh cpp>
 +#include <iostream>
 +using namespace std;
 +
 +class Rectangle {
 +private:
 +    int width, height;
 +public:
 +    Rectangle() {
 +        width = 1;
 +        height = 1;
 +    }
 +    Rectangle(int w, int h) {
 +        width = w;
 +        height = h;
 +    }
 +    int calcArea() {
 +        return width * height;
 +    }
 +};
 +
 +int main() {
 +    Rectangle a;  // 매개 변수가 없는 생성자가 호출된다. 너비와 높이가 1로 설정된다.
 +    Rectangle b {4, 3};  // 매개 변수가 있는 생성자가 호출된다.
 +    cout << a.calcArea() << endl;  // 1
 +    cout << b.calcArea();  // 12
 +
 +    return 0;
 +}
 +</sxh>
 +
 +이렇게 매개 변수가 없는 생성자를 기본 생성자라고 한다. 기본 생성자는 객체를 생성할 때 인수를 주지 않으면 자동으로 호출된다.\\
 +
 +<color #ed1c24>**다만, 기본 생성자를 호출할 때 소괄호를 사용하면 안된다. 컴파일러가 함수를 정의하는 것으로 생각하기 때문이다.**
 +</color>
 +
 +<sxh cpp>
 +Rectangle a;  // OK. 기본 생성자가 호출된다.
 +Rectangle b();  // X. 기본 생성자가 아니다.
 +</sxh>
 +\\
 +====예제: 평면 위의 점====
 +2차원 평면 위의 한 점을 나타내는 클래스 Point를 생성자를 포함하여 작성하라.\\
 +멤버 변수는 private으로, 멤버 함수는 public으로 설정하라.\\
 +따로 좌표를 설정하지 않으면 기본 좌표를 (0, 0)으로 설정하라.\\
 +객체의 좌표를 출력하는 멤버 함수는 클래스 외부에 정의하라.
 +
 +  x = 0, y = 0
 +  x = 2, y = 3
 +\\
 +답안 예시
 +<sxh cpp>
 +#include <iostream>
 +using namespace std;
 +
 +class Point {
 +private:
 +    int x, y;
 +
 +public:
 +    Point() {
 +        x = 0;
 +        y = 0;
 +    }
 +
 +    Point(int a, int b) {
 +        x = a;
 +        y = b;
 + }
 +
 +    void printXY();
 +};
 +
 +int main() {
 +    Point p;
 +    Point q(2, -3);
 +
 +    p.printXY();
 +    q.printXY();
 +
 +    return 0;
 +}
 +
 +void Point::printXY() {
 +    cout << "x = " << x << ", y = " << y << endl;
 +}
 +</sxh>
 +====5.3. 디폴트 인수를 사용하는 생성자====
 +생성자의 매개변수는 디폴트 값을 가질 수 있다.
 +
 +<sxh cpp>
 +#include <iostream>
 +using namespace std;
 +
 +class Rectangle {
 +private:
 +    int width, height;
 +public:
 +    Rectangle(int w = 1, int h = 1) {
 +        width = w;
 +        height = h;
 +    }
 +    int calcArea() {
 +        return width * height;
 +    }
 +};
 +
 +int main() {
 +    Rectangle a;
 +    Rectangle b{4, 3};
 +    cout << a.calcArea() << endl;  // 1
 +    cout << b.calcArea();  // 12
 +
 +    return 0;
 +}
 +</sxh>
 +
 +====5.4. 멤버 초기화 리스트====
 +앞서 클래스 Rectangle의 생성자에서 멤버 변수를 다음과 같이 초기화했다.
 +
 +<sxh cpp>
 +class Rectangle {
 +private:
 +    int width, height;
 +public:
 +    Rectangle(int w, int h) {
 +        width = w;
 +        height = h;
 +    }
 +};
 +</sxh>
 +
 +하지만 이것은 모두 할당이지 초기화를 해준 것이 아니다.\\
 +생성자 함수가 실행될 때 멤버 변수인 width와 height가 생성된 후, 생성자 본문이 실행되어 값이 할당된다.\\
 +이는 유효한 방법이지만 초기화보다 효율적이지 않다.\\
 +게다가 어떤 종류는 선언과 동시에 초기화를 해 주어야 한다.
 +
 +<sxh cpp>
 +class Rectangle {
 +private:
 +    const int width;
 +    int& height;
 +public:
 +    Rectangle(int w, int& h) {
 +        width = w;  // const 변수는 할당할 수 없다.
 +        height = h;  // 참조 변수는 선언과 동시에 초기화되어야 한다.
 +    }
 +};
 +</sxh>
 +
 +이런 문제를 해결하기 위해 C++에서는 초기화 리스트를 통해 멤버 변수를 초기화할 수 있다.
 +<sxh cpp>
 +Rectangle(int w, int h) : width(w), height(h) {}  // width를 w로, height를 h로 초기화한다.
 +</sxh>
 +
 +또한, 기본값이 지정되어 있더라도 생성자 멤버 초기화 리스트가 가장 우선시된다.
 +<sxh cpp>
 +class Rectangle {
 +public:
 +    int width = 1;
 +    int height = 1;
 +    Rectangle(int w, int h) : width(w), height(h) {}
 +};
 +
 +int main() {
 +    Rectangle r {2};  // 값을 하나만 전달하면 앞에서부터 차례대로 채운다.
 +    cout << r.width << endl;  // 2
 +    cout << r.height;  // 1
 +</sxh>
 +\\
 +====예제: 시간====
 +시간을 나타내는 클래스 Time을 작성하라.\\
 +시와 분을 입력받아 시간 객체를 생성하라.\\
 +멤버 초기화 리스트를 이용하여 객체를 초기화하라.\\
 +다음을 생성자 함수에서 수행하라.\\
 +  * 입력받은 시가 0 이상 24 미만의 정수가 되도록 24를 더하거나 뺄 것\\
 +  * 입력받은 분이 0 이상 60 미만의 정수가 되도록 60을 더하거나 뺄 것\\
 +입력받은 시간을 출력하는 멤버 함수를 작성하라.\\
 +  시: -33
 +  분: 77
 +  15시 17분
 +\\
 +답안 예시
 +<sxh cpp>
 +#include <iostream>
 +using namespace std;
 +
 +class Time {
 +private:
 +    int hour, minute;
 +
 +public:
 +    Time(int h, int m) : hour(h), minute(m) {
 +        while (hour < 0) hour += 24;
 +        while (hour >= 24) hour -= 24;
 +        while (minute < 0) minute += 60;
 +        while (minute >= 60) minute -= 60;
 +    }
 +
 +    void printTime() {
 +        cout << hour << "시 " << minute << "분" << endl;
 +    }
 +};
 +
 +int main() {
 +    int h, m;
 +
 +    cout << "시 : ";
 +    cin >> h;
 +    cout << "분 : ";
 +    cin >> m;
 +
 +    Time t(h, m);
 +
 +    t.printTime();
 +
 +    return 0;
 +}
 +</sxh>
 +=====6. 접근 제어=====
 +====6.1. 접근 지정자====
 +접근 제어란 외부에서 특정 멤버 변수나 함수에 접근하는 것을 제어하는 것이다.\\
 +''public:''을 붙이면 공개 멤버가 되어 클래스 밖에서도 멤버에 직접 접근할 수 있다.\\
 +''private:''을 붙이면 전용 멤버가 되어 클래스 외부에서는 접근할 수 없고, 클래스의 다른 멤버만 해당 멤버에 접근할 수 있다.\\
 +''public:''과 ''private:''을 접근 지정자라고 한다.\\
 +클래스의 모든 구성원은 기본적으로 private이므로 외부에서 직접 접근하기 위해서는 public 키워드를 사용해야 한다.\\
 +
 +====6.2. 접근 제어의 필요성====
 +우리는 앞에서 Rectangle 클래스를 작성했다.\\
 +그런데 만약에 width와 height가 모두 public인데 실수로 이 값들을 0 이하로 변경했다면 어떨까?\\
 +도형의 변 길이는 0 이하가 될 수 없으므로 이는 잘못된 값이 된다.\\
 +이러한 실수를 방지하기 위해 공개해도 되는 멤버와 공개해서는 안되는 멤버를 구분한다.\\
 +
 +====6.3. 접근자와 설정자====
 +Rectangle 클래스에서 width와 height 변수를 비공개로 설정했다면 객체의 멤버 변수 값을 직접 변경하거나 읽어올 수 없다.\\
 +따라서 우리는 private으로 선언된 멤버 변수를 외부로 전달하거나 외부에서 안전하게 멤버 변수의 값을 변경할 수 있는 함수를 만들어 사용한다.\\
 +이를 각각 접근자, 설정자라고 부른다.
 +
 +<sxh cpp>
 +class Rectangle {
 +private:
 +    int width = 1;
 +    int height = 1;
 +public:
 +    Rectangle(int w, int h) : width(w), height(h) {}
 +    int getWidth() {return width}
 +    int getHeight() {return height}  // 접근자
 +    void setWidth(int w) : width(w) {}
 +    void setHeight(int h) : height(h) {}  // 설정자
 +};
 +
 +int main() {
 +    Rectangle r {2};
 +    r.setHeight(3);
 +    cout << r.getWidth() << " " << r.getHeight();  // 2 3
 +
 +    return 0;
 +}
 +</sxh>
 +
 +====예제====
 +다음 빈칸을 채워 자신의 학과, 학번, 이름이 출력되도록 만들어라.
 +<sxh cpp>
 +#include <iostream>
 +#include <string>
 +using namespace std;
 +
 +class Student {
 +private:
 +    ____________________
 +    ____________________
 +    ____________________
 +public:
 +    Student() : department("미정"), num(2021000000), name("홍길동") {}
 +
 +    void setDepartment(__________) {
 +        ____________________
 +    }
 +    void setNum(__________) {
 +        ____________________
 +    }
 +    void setName(__________) {
 +        ____________________
 +    }
 +    string getDepartment() {
 +        ____________________
 +    }
 +    int getNum() {
 +        ____________________
 +    }
 +    string getName() {
 +        ____________________
 +    }
 +};
 +
 +int main() {
 +    ____________________
 +
 +    ____________________
 +    ____________________
 +    ____________________
 +
 +    cout << "학과: " << ____________________ << endl;
 +    cout << "학번: " << ____________________ << endl;
 +    cout << "이름: " << ____________________ << endl;
 +}
 +</sxh>
 +
 +답안 예시
 +<sxh cpp>
 +#include <iostream>
 +#include <string>
 +using namespace std;
 +
 +class Student {
 +private:
 +    string department;
 +    int num;
 +    string name;
 +public:
 +    Student() : department("미정"), num(2021000000), name("홍길동") {}
 +
 +    void setDepartment(string s) {
 +        department = s;
 +    }
 +    void setNum(int n) {
 +        num = n;
 +    }
 +    void setName(string s) {
 +        name = s;
 +    }
 +    string getDepartment() {
 +        return department;
 +    }
 +    int getNum() {
 +        return num;
 +    }
 +    string getName() {
 +        return name;
 +    }
 +};
 +
 +int main() {
 +    Student s;
 +
 +    s.setDepartment("기계공학부");
 +    s.setNum(2020170716);
 +    s.setName("윤호연");
 +
 +    cout << "학과: " << s.getDepartment() << endl;
 +    cout << "학번: " << s.getNum() << endl;
 +    cout << "이름: " << s.getName() << endl;
 +}
 +</sxh>