본문 바로가기
개발/C++ (98,03,11,14,17,20,23)

Modern C++ : 클래스(Class) (98, 11, 17)

by snowoods 2025. 9. 17.

Modern C++

 

클래스 (Class)

 

개요

C++에서 class는 사용자 정의 타입을 만드는 핵심적인 기능입니다. 클래스는 데이터(멤버 변수)와 해당 데이터를 처리하는 함수(멤버 함수)를 하나로 묶어 관리하며, 객체 지향 프로그래밍(OOP)의 기본이 됩니다. 클래스를 통해 데이터 캡슐화, 상속, 다형성 등 OOP의 주요 특징을 구현할 수 있습니다.

C++ 버전별 주요 키워드 도입 시기

  • C++98: class 키워드 자체는 C++의 초기 버전부터 존재했습니다.
  • C++11: default, delete 키워드가 도입되어 컴파일러가 생성하는 기본 멤버 함수(생성자, 소멸자 등)를 명시적으로 사용하거나 삭제할 수 있게 되었습니다.
  • C++17: std::string_view가 도입되어, 문자열을 복사하지 않고도 읽기 전용으로 안전하고 효율적으로 다룰 수 있게 되었습니다.

 

내용 설명

클래스는 일반적으로 헤더 파일(.h)에 선언하고, 소스 파일(.cpp)에 멤버 함수를 정의하는 방식으로 구현합니다.

  • 선언 (Header): 클래스의 구조를 정의합니다. 멤버 변수와 멤버 함수의 시그니처를 선언합니다.
    • public, private 접근 지정자를 사용하여 외부 접근 수준을 제어합니다. public 멤버는 어디서든 접근 가능하지만, private 멤버는 해당 클래스의 멤버 함수 내에서만 접근할 수 있습니다. (캡슐화)
    • 생성자: 객체가 생성될 때 호출되는 특별한 멤버 함수입니다. 예제에서는 멤버 이니셜라이저 리스트(: name(_name), ...)를 사용하여 멤버 변수를 효율적으로 초기화합니다.
    • 소멸자: 객체가 소멸될 때 호출됩니다. ~Axe() = default;는 컴파일러가 생성하는 기본 소멸자를 사용하겠다는 의미입니다.
    • const 멤버 함수: get_name() const처럼 함수 뒤에 const를 붙이면, 해당 함수가 멤버 변수의 상태를 변경하지 않음을 명시합니다.
  • 정의 (Source): 헤더에 선언된 멤버 함수의 실제 동작을 구현합니다. Axe::get_name()처럼 :: (스코프 확인 연산자)를 사용하여 어떤 클래스에 속한 함수인지 명시합니다.
  • 사용: main 함수에서 Axe 클래스의 인스턴스(객체)를 생성하고, . 연산자나 -> 연산자를 통해 public 멤버 함수를 호출하여 사용합니다.

 

예제 코드

Weapons.h (헤더 파일)

#pragma once // 헤더 중복 포함 방지

#include <string>
#include <string_view>

class Axe
{
public:
    // 생성자: std::string_view를 사용해 불필요한 문자열 복사를 방지
    Axe(const std::string_view &_name,
        const float _damage,
        const float _attack_speed)
        : name(_name), damage(_damage), attack_speed(_attack_speed){};

    // 컴파일러가 생성하는 기본 소멸자 사용 (C++11)
    ~Axe() = default;

    // 멤버 변수의 값을 반환하는 Getter 함수들
    std::string get_name() const;
    float get_damage() const;
    float get_attack_speed() const;

private:
    // 멤버 변수
    std::string name;
    float damage;
    float attack_speed;
};

 

Weapons.cpp (정의 파일)

#include "Weapons.h"

std::string Axe::get_name() const
{
    return name;
}

float Axe::get_damage() const
{
    return damage;
}

float Axe::get_attack_speed() const
{
    return attack_speed;
}

 

main.cpp (사용 예시)

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

int main()
{
    // 클래스 인스턴스(객체) 생성
    const auto axe = Axe{"Great dwarfen axe", 12.0F, 1.2F};
    std::cout << axe.get_name() << '\n';

    // 객체 포인터를 통한 멤버 접근
    const auto axe_ptr = &axe;
    std::cout << axe_ptr->get_name() << '\n';

    return 0;
}

 

실행 결과

Great dwarfen axe
Great dwarfen axe

 

활용팁

  • 캡슐화: 클래스의 멤버 변수는 private으로 선언하고, public 멤버 함수(Getter/Setter)를 통해서만 접근하도록 하여 데이터의 무결성을 유지하는 것이 좋습니다.
  • 선언과 정의 분리: 클래스의 선언(인터페이스)과 정의(구현)를 분리하면 코드의 가독성과 재사용성이 높아집니다. 또한, 구현부가 변경되어도 헤더 파일을 포함하는 다른 코드들은 재컴파일할 필요가 없어 빌드 시간을 단축시킬 수 있습니다.
  • const 활용: 상태를 변경하지 않는 멤버 함수에는 const를 붙여 실수를 방지하고, const 객체에서도 해당 함수를 호출할 수 있도록 하는 것이 좋은 습관입니다.
  • std::string_view (C++17): 생성자나 함수 인자로 문자열을 받을 때, 복사가 필요 없는 읽기 전용이라면 const std::string&보다 std::string_view를 사용하는 것이 더 효율적입니다.