[C++] 객체 지향 프로그래밍과 클래스

유지연·2023년 3월 21일
0

C++

목록 보기
1/7

👋 대~충 알고 넘어 갔던 객체지향 프로그래밍과 클래스의 개념을 다시 공부해보자!


✏️ 객체지향 프로그래밍 (OOP)

✔️ 객체지향 프로그래밍의 정의

프로그램에서 필요한 데이터를 추상화 시켜 상태와 행위를 가진 객체로 만들고, 객체 간의 유기적인 상호작용을 통해 로직을 구성하는 프로그래밍 방법이다.

✔️ 객체지향 프로그래밍의 장단점

  • 장점
    코드 재사용이 용이: 클래스의 재사용 혹은 상속
    유지 보수가 쉬움: 클래스 단위로 수정이 가능
    대형 프로젝트에 적합: 클래스 단위로 모듈화하여 개발하기 때문에 업무 분담 편리

  • 단점
    처리 속도가 상대적으로 느림
    객체 수가 많아짐에 따라 용량이 커짐
    설계가 복잡해질 수 있음

✔️ 객체지향 프로그래밍의 특징

  • 추상화 Abstraction
    객체에서 공통된 속성과 행위를 추출하는 것 (클래스를 설계)

  • 캡슐화 Encapsulation
    데이터 구조와 데이터를 다루는 방법을 결합시켜 묶는 것 (변수와 함수를 하나로 묶음)
    접근제어자를 통해 데이터를 은닉하고, 접근을 제한할 수 있음
    → 외부에서 접근할 필요가 없는 것들에 대해 제한하여 오류를 방지하고 유지보수 효울을 높임
    객체 내의 모듈 간의 요소가 밀접한 관련이 있는 것으로 구성하여 응집도를 높여야 함

    • 접근제어자
      Public: 모두 접근 가능
      Protected: 상속이나 같은 패키지 내의 클래스에서만 접근 가능
      Private: 외부 접근 불가능

    캡슐화의 목적?
    코드의 재활용, 접근제어자를 통한 정보은닉 (높은 응집도, 낮은 결합도)

    절차지향 프로그래밍에도 라이브러리를 통해 변수와 함수를 재활용 할 수 있었다. 하지만 코드의 수정이 일어났을 때 영향 범위를 예측하기 어렵다는 문제가 있었다. 객체지향 프로그래밍에서는 캡슐화를 통해 접근제어자를 통해 적절히 제어 권한을 통제하기 때문에 코드의 수정이 일어났을 때 책임이 있는 객체만 수정하면 된다. 따라서 영향 범위를 예측하는 것이 수월해졌다!

  • 상속성 Inheritance
    클래스의 속성과 행위를 하위 클래스에 물려주거나, 상위 클래스에게 물려 받는 것
    새로운 클래스가 기존 클래스의 데이터와 연산을 할 수 있게 해줌

  • 다형성 Polymorphism
    하나의 변수명와 함수명이 상황에 따라 다른 의미로 해석될 수 있는 것
    → 오버라이딩(Overriding), 오버로딩(Overloading)이 가능

    • 오버라이딩 Overriding
      상위 클래스가 가지고 있는 메소드를 하위 클래스에서 재정의 하여 사용하는 것
    • 오버로딩 Overloading
      같은 이름의 함수를 여러 개 정의, 매개변수의 타입, 개수에 따라 다르게 호출할 수 있게 하는 것


✏️ 클래스 Class

✔️ 클래스의 정의

C의 구조체처럼 사용할 수 있는 사용자 지정 자료형 (user defined type)
추상화를 거쳐 집단에 속하는 속성(attribute)과 행위(behavior)를 변수메소드로 정의한 것

인스턴스: 클래스에서 정의한 것을 토대로 메모리에 할당하여 실제 프로그램에서 사용되는 데이터

✔️ 클래스의 사용

#include <iostream>
using namespace std;

class Player {
private:

    string name;
    int age;
    int hp;
    string sex;

public:

    Player(string player_name, int player_age, int player_hp, string player_sex) {
        name = player_name;
        age = player_age;
        hp = player_hp;
        sex = player_sex;
    } //생성자 (클래스명과 동일)

    ~Player() {
        cout << "객체가 소멸됩니다!";
    } //소멸자 (~클래스명)

    void attack( ) {
        cout << name << "is attacked!" << "\n";
        cout << name << "'s hp: " << hp << " -> " << hp-10 << "\n";
        hp -= 10;
    }
    void print_info() {
        cout << "name: " << name << "\n";
        cout << "sex: " << sex << "\n";
        cout << "age: " << age << "\n";
    }
    void newyear(int age);
};

void Player::newyear(int age) { 
    age += 1;
} //클래스 외부에서 멤버 함수 정의

int main() {
    Player p1("Star", 18, 100, "M");
    p1.attack();
    p1.print_info();
    return 0;
} 

위 예시를 보며 클래스의 사용 방법에 대해 자세히 알아보자!

  • 클래스의 선언
    Player 클래스의 속성: name, age, hp, sex → 멤버 변수
    Player 클래스의 메소드: attack( ), print_info( ), newyear( ) → 멤버 함수
    클래스 내의 변수와 함수를 각각 멤버 변수, 멤버 함수라고 부른다.

  • 접근제어자 private, public
    Player 클래스의 멤버 변수는 모두 private으로 선언됨
    → 외부에서 멤버 변수에 접근 제한

    • cout << p1.name;
      → error C2248: 'Player::name': private 멤버('Player' 클래스에서 선언)에 액세스 할 수 없습니다.

    클래스 내의 멤버에 대해 접근제어자를 명시해주지 않으면 모두 private으로 간주한다.

  • 클래스 외부에서 멤버 함수를 정의하는 경우
    멤버 함수의 선언은 반드시 클래스 내부에서 일어나야 함
    외부에서 멤버 함수를 정의하는 경우 클래스명::함수명 으로 명시
    → 만약 "클래스명::"이 없는 경우 전역 함수의 정의가 되어버림

  • 생성자와 소멸자

    • 생성자
      객체를 생성함과 동시에 자동으로 호출되는 멤버 함수

      특징 1. 클래스명과 함수명이 동일하며 반환값이 없음
      특징 2. 오버로딩이 가능함에 따라 여러 개의 생성자 선언 가능
      → 객체를 생성할 때 지정하는 인자에 따라 맞는 생성자가 호출 됨
      특징 3. 객체를 생성하는 시점에 필요한 멤버들을 초기화 시킬 수 있음
      특징 4. 생성자를 따로 선언하지 않는 경우, 매개변수가 없는 기본 생성자가 자동으로 생성

    • 소멸자
      객체가 소멸될 때 자동으로 호출되는 멤버 함수

      특징 1. 클래스명에 "~"를 붙여 함수명을 지정하며 반환값이 없음
      특징 2. 객체가 사라지는 시점에 인스턴스가 할당받은 메모리 해제와 같은 마무리 작업
      특징 3. 해당 인스턴스가 생성된 범위가 끝나는 순간 생성자의 역순으로 호출
      특징 4. 소멸자를 따로 선언하지 않는 경우, 기본 소멸자가 자동으로 생성
      new로 동적 할당된 객체에 대해 반드시 delete로 메모리 해체 필요!



객체지향 프로그래밍과 클래스의 개념에 대해 정리해보았다!
부족한 내용에 대해서는 차차 공부하면서 더 추가해야겠다. 네버엔딩스터디...😹

[이미지 출처] https://zoosso.tistory.com/868
[내용 참고] https://jeong-pro.tistory.com/95
https://salix97.tistory.com/286
https://bloghelloworld.tistory.com/115
https://nybot-house.tistory.com/20

profile
Keep At It

0개의 댓글