[C++] Class

Class에 대하여

클래스(Class)는 객체지향 프로그래밍에서 데이터와 이를 조작하는 메서드를 하나로 묶는 기본적인 단위다. 클래스는 객체를 생성하기 위한 설계도와 같은 역할을 수행한다.

Class 구조

C++에서 클래스는 다음과 같은 기본 구조를 가진다.


class ClassName {
private:
    int memberVariable; // 멤버 변수 (데이터, 어트리뷰트)

public:
    ClassName(); // 생성자(Constructor)

    ~ClassName(); // 소멸자(Destructor)

    void memberFunction(); // 멤버 함수 (메서드)

protected:
    void toHeriage();
};

접근 제한자

접근 제한자는 private, protected, public 키워드를 사용해 멤버 변수와 함수의 접근 권한을 정의한다.

  1. public: 가장 기본적인 영역으로, 클래스 외부에서 자유롭게 사용할 수 있는 멤버들이 위치해 있다. 클래스에서 접근 제한자를 별도로 지정하지 않는다면, 모든 멤버들은 public한 성격을 갖는다.

  2. private: 이 영역에 위치한 멤버들은 클래스 내부에서만 접근이 가능하다. 클래스의 인스턴스를 만들어도 private 영역에 위치한 멤버들은 접근할 수 없다.

  3. protected: 일반적으로 외부에서 접근할 수 없지만, 상속받은 클래스에서는 접근할 수 있다.

생성자와 소멸자

  1. 생성자 ClassName(params); 생성자는 객체가 생성될 때 호출되는 특별한 함수다. 별도의 파라미터를 지정해주면, 객체가 생성될 때 파라미터들을 넣어줘야만 한다.

  2. 소멸자 ~ClassName(params); 소멸자는 객체가 소멸될 때 호출되는 함수다.

멤버 함수(메서드)와 멤버 변수(어트리뷰트)

  1. 정의하는 방법 멤버 변수와 함수는 클래스의 속성과 행동을 정의한다. 멤버 변수와 함수를 쓰는 방법은 C++에서 변수와 함수를 정의할 때와 동일하다.
    변수의 경우, 해당 변수의 타입을 지정해주고 함수의 경우, 반환값의 타입을 기준으로 타입을 지정한다. (없으면 void)

  2. 정적 멤버 (Static Member) 클래스 자체에 귀속되며, 모든 객체가 공유한다. 메모리 공간에 영향을 미치기 때문에 정적 멤버는 적재적소에만 사용하는 것이 좋다. 정적 함수 / 변수 모두 선언 가능하다.

  class Counter {
  private:
      static int count;

  public:
      static void increment() {
          ++count;
      }
  };
  1. 클래스 내부에서 멤버 접근
    클래스 내부에서 멤버 변수/함수를 접근할 때는 this.(memberName) 식으로 this.을 앞에 붙여주어야 한다.

  2. 클래스 외부에서 멤버 접근
    클래스 외부에서 멤버 변수/함수를 접근할 때는 클래스 인스턴스를 this 자리에 위치시키면 된다.

  // ex

  ClassName clas();
  clas.memberFunction();

멤버 초기화 리스트

클래스의 내부 멤버 객체를 할당하는 방법에는 ‘할당’과 ‘초기화’가 있다.

  • 할당
class Example {
private:
    int x;
    int y;

public:
    Example(int a, int b) {
      // 할당 
      x = a;
      y = b;
    }
};
  • 초기화
class Example {
private:
    int x;
    int y;

public:
    // 초기화 
    Example(int a, int b) : x(a), y(b) {}
};

초기화는 생성자 선언부 옆에 :로 시작해 초기화된다.
정의된 멤버(초기화 하고자하는 값)으로 사용할 수 있다.

일반적으로 클래스에서 멤버의 값을 할당하는 데엔 선언보다는 초기화가 이용된다.

  1. 멤버를 초기화하는 방법은 할당하는 것보다 메모리 효율적이라는 장점이 있다.
  2. 할당은 초기화가 아니기 때문에, 선언되기 위해서 초기화가 필수적인 참조와 정적 멤버는 멤버 초기화 방법으로만 정의될 수 있다.
  3. 디폴트 생성자가 없는 클래스가 타입인 멤버 데이터가 클래스 안에 있다면 반드시 초기화 방법을 이용해야 한다.

=> 선언은 초기화에 비해 효율성이 낮고, 사용할 수 없는 타입들이 존재한다.

헤더 파일 분리

C++은 재사용 가능한 코드를 만들고, 쉬운 유지 보수를 위해 클래스의 선언과 구현을 분리한다.
클래스의 선언부는 헤더 파일에, 구현부는 cpp 파일로 정의한다.

  1. 헤더 파일(.h)

클래스의 선언(멤버 변수와 함수의 프로토타입)을 포함한다.

// Example.h
#ifndef EXAMPLE_H
#define EXAMPLE_H

class Example {
private:
    int value;

public:
    Example(int v);
    int getValue();
};

#endif
  • #ifndef ~ #endif 는 중복된 헤더 파일이 로드되지 않도록 방지한다.
  • 헤더 파일과 구현 파일을 나누어 구현할 때 사전 할당값(변화 가능)은 헤더 파일에만 정의한다.
  • 여러 개의 클래스와 함수를 하나의 헤더 파일에 묶는 것 또한 가능하다. #ifndef ~ #endif 사이에 하나의 헤더로 불러오고 싶은 클래스와 매서드들을 위치하면, #include <header.h>만으로 여러 개의 클래스와 메서드를 불러올 수 있다.
  1. 구현 파일(.cpp)

클래스 멤버 함수의 구체적인 구현을 포함한다.

코드 복사
// Example.cpp
#include "Example.h"

Example::Example(int v) : value(v) {}

int Example::getValue() {
    return value;
}
  1. 사용 예시

헤더 파일을 포함한 후 객체를 생성하고 사용한다.

#include <iostream>
#include "Example.h"

int main() {
    Example ex(42);
    std::cout << ex.getValue() << std::endl;
    return 0;
}



Comments