" /> C++ 3주차 객체와 클래스 | BlackWerf's Blog
포스트

C++ 3주차 객체와 클래스

포인터

사용 방법

  • 자료형 *변수명;

  • &변수 : 변수의 주소
  • 변수 : 변수의 값

  • 예시

    1
    2
    3
    4
    5
    
    char v = 10;
    char *p;
    p = &v;
    cout << v;
    cout << p;
    


특징
  • 일반적인 변수와 다르게 주소를 저장함

포인터와 배열의 관계

  • 포인터 변수 + 1

    • 포인터 변수의 타입의 크기만큼 증가함
  • 배열의 변수

    • 배열의 변수는 배열의 첫번째 공간의 주소 보유

    • *(p+1) = p[1]

  • 포인터와 배열은 동일한 문법으로 데이터 접근 가능

절차적 프로그래밍

종류

  • C, 포트란…

특징

  • 작업의 순서를 기반으로 프로그래밍
  • 기능에 중점
  • 직관적, 공정, 정해진 루틴의 프로그램 잓성에 유리

장점

  • 컴퓨터의 처리구조와 유사함
    • 실행속도가 빠름
  • 프로그램의 흐름을 쉽게 추적이 가능

단점

  • 각 코드의 유기성이 높음
    • 유지보수의 난이도가 상승
      • 새 기능이나 데이터 추가가 힘들고
      • 부분 고장시 전체 고장으로 확대
  • 실행 순서가 정해짐
    • 코드 순서가 바뀔 경우 동일 결과를 보장하기 힘듬
  • 디버깅이 힘듬

구조적 프로그래밍

종류

  • C++, C#, Java, Python
  • 데이터와 관련된 동작의 그룹을 객체로 정의
  • 데이터 중심이며 안정성이 높음
  • 데이터와 동작이 변할 때 유지 보수가 유리함
  • 데이터와 관련된 동작의 오류가 발생했을 때, 디버깅에 유리함

특징

  • 캡슐화
    • 속성과 메소드를 하나로 묶고, 실제 내용은 외부에서 접근 할 수 없도록 접근을 제한함
  • 추상화
    • 객체의 공통적인 속성, 기능만 구현하는 것
  • 상속
    • 상위 클래스의 속성, 메소드를 하위 클래스에서 전부 구현하는 것
  • 다형성
    • 하나의 객체가 여러 타입을 가질 수 있는 것
      • 오버라이드와 오버라이딩이 존재함

장점

  • 모듈화 및 캡슐화 -> 유지보수에 용의함
  • 객체지향 언어
    • 현실세계와 유사성에 의해 코드 작성이 쉬움
  • 객체 자체가 하나의 프로그램
    • 재사용 용의

단점

  • 상대적으로 속도가 느리며, 많은 메모리를 사용
  • 코드 설계에 절차적 프로그래밍에 비하여 많은 시간이 소모됨

클래스

정의

  • 객체 생성을 위해 정의된 형식
  • 클래스는 객체가 아니며, 실체도 아님
  • 멤버 변수/함수 선언

선언 방법

1
2
3
4
class 클래스이름{
    public: 접근제한자(private  다른 접근 제한자 사용 가능)
        변수타입 변수명;
};

구현 방법

1
2
3
함수의 리턴타입 클래스이름 :: 멤버함수명과 매개변수(){
	//클래스 내용
}


클래스와 캡슐화

자동차 클래스{

최고속도(속성)

​ ↑(속도제한)

달린다(동작)

}

↑(보호)

관찰자*현재속도만 관찰이 가능)


객체

  • 생성될 때 클래스의 모양을 그대로 가짐
  • 멤버 변수와 함수로 구성됨
  • 메모리에 생성됨
    • 실체(Instance)라고도 불림
  • 하나의 클래스로 여러 개의 객체를 생성 가능함
  • 객체들은 상호 별도의 공간에 생성됨


멤버 변수와 멤버 함수

멤버 변수
  • 클래스 내부에 존재하는 데이터
    • Ex) 속도, 전진/후진
멤버 함수(메소드)
  • 멤버 변수에 대한 접근이 가능함
  • 객체의 동작을 정의함
    • 달린다, 멈춘, 좌/우 방향전환
예제 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Circle {
public:
    int radius;
    double getArea();
};

double Circle:: getArea() {
        return 3.14 * radius * radius;
    };

int main(){
    Circle donut;
    donut.radius = 10;
    double area = donut.getArea();
    cout << "크기: " << area << endl;

    Circle pizza;
    pizza.radius = 30;
    double area2 = pizza.getArea();
    cout << "크기: " << area2 << endl;
}

결과

1
2
크기: 314
크기: 2826


예제 2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Rectangle {
public:
    int width, height;
    int getArea();
};

int Rectangle::getArea() {
    return width * height;
}


int main(){
   Rectangle rect;
   rect.width = 10;
   rect.height = 20;
   cout << "사각형 면적: " << rect.getArea() << endl;
}

결과

1
사각형 면적: 200


생성자

  • 객체가 생성되는 시점에서 자동으로 호출되는 멤버 함수
  • 클래스 이름과 같은 멤버 함수

예시

1
2
3
4
5
6
class Circle{
    Circle();
    Circle(int radius);
}
Circle::Circle(){ }
Circle::Circle(int radius) {}

목적

  • 객체 생성 시 객체에 필요한 초기화를 위해
    • 멤버 변수 값 초기화, 메모리 할당, 파일 열기, 네트워크 연결…

특징

  • 생성자 이름

    • 반드시 클래스 이름과 동일해야 함


  • 생성자는 리턴타입을 선언하지 않음

    • 리턴 타입 없음(Void 타입도 불가능)


  • 객체 생성 시 한번만 호출

    • 자동으로 호출되며, 임의로 호출이 불가능함
    • 각 객체마다 생성자가 실행됨


  • 생성자는 중복 가능

    • 생성자는 한 클래스 내에 여러개가 가능함
    • 중복된 생성자 중 1개만 실행


  • 생성이 안되있을 경우 기본 생성자가 자동으로 생성됨

    • 기본 생성자 - 매개 변수 없는 생성
    • 컴파일러에 의해 자동 생성

예제

  • 예제1

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    
    class Circle
    {
    public:
        int radius;
        Circle(); //매개변수가 없는 생성자
        Circle(int r); //매개변수가 있는 생성자
        double getArea();
    };
    Circle::Circle() {
        radius = 10;
        cout << "반지름 " << radius << " 원 생성" << endl;
    }
    Circle::Circle(int r) {
        radius = r;
        cout << "반지름 " << radius << "원 생성" << endl;
    }
    double Circle::getArea() {
        return 3.14 * radius * radius;
    }
      
      
    int main(){
            Circle donut;
        double area = donut.getArea();
        cout << "면적 " << area << endl;
        Circle pizza(30);
        area = pizza.getArea();
        cout << "pizza 면적 : " << area << endl;
    }
    

    결과

    1
    2
    3
    4
    
    반지름 10 원 생성
    면적 314
    반지름 30원 생성
    pizza 면적 : 2826
    


생성자를 호출하는 생성자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//코드 중복 1
Cirlce :: Circle(){
    radius = 1;
    cout << "반지름  " << radius << " 원 생성 " << endl;
}
//코드 중복 2
Cirlce :: Circle(int r){
	radius = r;
    cout << "반지름  " << radius << " 원 생성 " << endl;
}

//간소화된 생성자 호출 생성자 코드 구현
Circle :: Circle() : Circle(1){}
Circle :: Circle(int r){
    radius = r;
    cout << "반지름 " << radius << " 원 생성 " << endl;
}
  • 예시 코드

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    
    using namespace std;
    #include <iostream>
      
    class Circle
    {
    public:
        int radius;
        Circle(); //위임 생성자
        Circle(int r); //타겟 생성자
        double getArea();
    };
      
      
    Circle::Circle() {
    	radius = 10;
    	cout << "반지름 " << radius << " 원 생성" << endl;
    }
    Circle::Circle(int r) {
    	radius = r;
    	cout << "반지름 " << radius << "원 생성" << endl;
    }
    double Circle::getArea() {
        return 3.14 * radius * radius;
    }
      
      
    int main()
    {
        Circle donut;
        double area = donut.getArea();
        cout << "면적 " << area << endl;
        Circle pizza(30);
        area = pizza.getArea();
        cout << "pizza 면적 : " << area << endl;
    }
    

    결과

    1
    2
    3
    4
    
    반지름 1 원 생성
    면적 3.14
    반지름 30 원 생성
    pizza 면적 : 2826
    


    생성자의 멤버 변수 초기화

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
    class Point 
    {
        int x, y;
    public:
        Point();
        Point(int a, int b);
    };
      
      
    //생성자 코드에서의 멤버 변수의 초기화
    Point :: Point() { x = 0; y = 0; }
    Point :: Point(int a, int b) { x = a; y = b; }
      
    //생성자의 서두에서 초기값으로 초기화하기
    Point :: Point() : x(0), y(0) {} //x,y를 0으로 초기화
    Point :: Point(int a, int b) : x(a), y(b) {} //x,y를 각각 a, b으로 초기화
      
    //클래스 선언부에서의 직접적인 값 초기화
    class Point{
        int x=0, y=0; //선언부에서 값을 직접 초기화
        .
        .
        .
    };
    

    예시 코드

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    class Point 
    {
        int x, y;
    public:
        Point();
        Point(int a, int b);
        void Show() { cout << "(" << x << "," << y << ")" << endl; };
    };
      
    Point::Point() : Point(0, 0) {} //위임 생성자
    Point::Point(int a, int b) : x(a), y(b) {} //타겟 생성자
      
      
    int main()
    {
    	Point origin;
    	Point target(10, 20);
    	origin.Show();
    	target.Show();
    }
    

    결과

    1
    2
    
    (0,0)
    (10,20)
    


기본 생성자

특징
  • 객체 생성시 1회 호출됨

  • 클래스에 생성자가 없을 경우, 컴파일러가 자동 생성함
    • 클래스 내부에 매개변수가 있는 생성자만 있을 경우, 매개변수 없이 객체를 생성할 경우 오류가 발생함
  • 매개변수가 없음
예제 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Rectangle
{
public:
    int width, height;
    Rectangle();
    Rectangle(int w, int h);
    Rectangle(int length);
    bool isSquare();
};
Rectangle::Rectangle() { width = height = 1; } //Rect1에서 호출됨
Rectangle::Rectangle(int w, int h) { width = w, height = h; } //Rect2에서 호출됨
Rectangle::Rectangle(int length) { width = height = length; } //Rect3에서 호출됨
bool Rectangle::isSquare() {
    if (width == height) return true;
    else return false;
}


int main(){
    Rectangle rect1, rect2(3, 5), rect3(3);
if (rect1.isSquare()) cout << "rect1은 정사각형" << endl;
if (rect2.isSquare()) cout << "rect2은 정사각형" << endl;
if (rect3.isSquare()) cout << "rect3은 정사각형" << endl;
}

결과

1
2
rect1은 정사각형
rect3은 정사각형
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.