[C++] OOP - 클래스와 메모리

chooha·2026년 1월 2일

C++

목록 보기
11/23

📚 C++ OOP와 클래스 개념

🔸 OOP - Class 소개

기본 개념

  • Class : 객체를 만들기 위한 정의, 설계도, 틀
  • Object : 클래스로부터 생성된 각각의 실체, 인스턴스

OOP의 4가지 핵심 특징
1. Abstraction (추상화)

  • 일반화(Generalization)와 모델링
  • 복잡한 현실 세계를 클래스로 단순화하여 표현
  1. Encapsulation (캡슐화)

    • private 접근 지정자를 통해 구현
    • 데이터와 메서드를 하나로 묶고 외부로부터 보호
  2. Inheritance (상속)

    • 기존 클래스의 특성을 물려받아 재사용
    • 코드의 재사용성과 확장성 향상
  3. Polymorphism (다형성)

    • Static Polymorphism : Function Overloading (컴파일 타임에 결정)
    • Dynamic Polymorphism : Function Overriding (virtual 키워드 사용, 런타임에 결정)

🔸 Object Alignment (객체 메모리 정렬)

메모리 정렬 예제

class Cat
{
public:
    void Speak();
private:
    double d8;    // 8 bytes
    int i4a;      // 4 bytes
    int i4b;      // 4 bytes
};

메모리 크기 변화

  • 위 코드의 경우: Cat 객체 크기 = 16 bytes

  • d8i4a의 선언 순서를 바꾸면: 24 bytes로 증가

Padding이 발생하는 이유

  • 메모리 정렬 규칙(Alignment Rule) 때문에 발생
  • 각 멤버 변수는 자신의 크기의 배수인 주소에서 시작해야 함
    • int (4 bytes) : 0, 4, 8, 12, 16, ... 주소에서 시작
    • double (8 bytes) : 0, 8, 16, 24, 32, ... 주소에서 시작
  • 전체 객체 크기는 가장 큰 멤버 변수 크기의 배수여야 함
  • CPU가 정렬되지 않은 메모리에 접근할 때 성능이 저하되거나 오류가 발생할 수 있어 컴파일러가 자동으로 패딩을 삽입함

메모리 최적화 팁

  • 구조체나 클래스 설계 시 멤버 변수를 크기 순으로 정렬하면 패딩을 최소화할 수 있음
  • 큰 타입(double, long long)을 먼저, 작은 타입(char, bool)을 나중에 배치
  • #pragma pack 지시자로 패딩을 제어할 수도 있지만, 성능 저하가 발생할 수 있으므로 주의 필요

🔸 alignas 키워드

False Sharing 문제

  • Cat arr[100]과 같은 배열이 있을 때 발생 가능
  • 캐시 라인(Cache Line)의 최소 단위는 64 bytes
  • Cat 객체가 24 bytes인 경우, 하나의 객체가 두 개의 캐시 라인에 나뉘어 저장될 수 있음
  • 이로 인해 false sharing이 발생하여 성능 저하 초래

alignas를 통한 해결

class alignas(32) Cat
{
    // ...
};
  • 객체를 32 bytes 단위로 정렬하여 false sharing 방지
  • 캐시 효율성 향상

🔸 Static in Class

1. Static Member Function (정적 멤버 함수)

  • 객체를 생성하지 않고도 호출 가능
  • 클래스 이름으로 직접 접근
Cat::StaticSpeak();

2. Static Member Variable (정적 멤버 변수)

  • 클래스 외부에서 명시적으로 초기화 필요
    class Cat {
        static int count;
    };
    int Cat::count = 0;  // 클래스 외부에서 초기화
  • Static 메모리 영역(데이터 세그먼트)에 할당됨
  • 모든 객체가 공유하는 변수
  • 프로그램 시작 시 초기화되고 프로그램 종료 시까지 유지됨

3. Static Variable in a Function (함수 내 정적 변수)

  • 함수 내부에서 선언된 정적 변수
    void func() {
        static int count = 0;  // 함수가 처음 호출될 때 초기화
        count++;
    }
  • 함수가 처음 호출될 때 초기화됨
  • 함수 호출이 끝나도 값이 유지됨

초기화 시점 비교

  • Static member variable: 프로그램 시작 전 (전역 변수와 동일)
  • Static variable in function: 함수가 처음 호출될 때 (지연 초기화)

🔸 this 키워드

this의 역할

  • 현재 객체의 주소를 가리키는 포인터
  • 멤버 함수 내에서 암묵적으로 사용됨

Static 멤버 함수의 제약

  • Static 멤버 함수는 특정 객체와 연결되어 있지 않음
  • 따라서 this 포인터가 존재하지 않음
  • 일반 멤버 변수나 멤버 함수를 사용할 수 없음
    • 이들은 this를 통해 호출되기 때문

this 포인터 활용

  • 멤버 변수와 매개변수 이름이 같을 때 구분
    void SetName(string name) {
        this->name = name;  // 멤버 변수와 매개변수 구분
    }
  • 메서드 체이닝 구현
    Cat& SetAge(int age) {
        this->age = age;
        return *this;  // 자기 자신을 반환
    }

🔸 inline, const, constexpr 정리

inline 키워드

  • 함수 호출 오버헤드를 제거하기 위한 키워드
  • 컴파일러에게 함수 본문을 호출 지점에 직접 삽입하도록 요청
  • 작고 자주 호출되는 함수에 사용하면 효과적
  • 클래스 내부에서 정의된 멤버 함수는 자동으로 inline 처리됨
  • 주의: 함수가 너무 크면 코드 크기가 증가할 수 있음 (컴파일러가 무시할 수 있음)
inline int Add(int a, int b) { return a + b; }
// 호출 시 → int result = a + b; 로 직접 삽입됨

const 키워드 (멤버 함수)

  • 멤버 함수가 객체의 상태(멤버 변수)를 변경하지 않음을 명시
  • const 객체는 const 멤버 함수만 호출할 수 있음
  • 함수 선언 뒤에 const를 붙여 사용
class Cat {
    int age;
public:
    int GetAge() const { return age; }  // ✅ 읽기만 가능
    void SetAge(int a) { age = a; }     // ❌ const 객체는 호출 불가
};

const Cat kitty;
kitty.GetAge();  // ✅ OK
kitty.SetAge(5); // ❌ 컴파일 에러

constexpr 키워드

  • 컴파일 타임에 값이 결정되는 상수 표현식
  • 런타임 성능 향상 (컴파일 시 계산 완료)
  • 함수에 사용하면 컴파일 타임에 실행 가능
  • C++11부터 도입, C++14/17에서 기능 확장
constexpr int Square(int x) { return x * x; }

int arr[Square(5)];  // 컴파일 타임에 arr[25]로 결정됨

// static member variable과 함께 사용
class Math {
    static constexpr double PI = 3.14159;  // 컴파일 타임 상수
};

const vs constexpr 비교

  • const: 런타임 또는 컴파일 타임 상수 (값 변경 불가)
  • constexpr: 반드시 컴파일 타임 상수 (더 엄격함)
const int a = 10;           // 컴파일 타임 상수
const int b = GetValue();   // 런타임 상수 (함수 호출 결과)

constexpr int c = 10;       // ✅ 컴파일 타임 상수
constexpr int d = GetValue(); // ❌ 컴파일 에러 (constexpr 함수여야 함)

<참고 자료>

코드없는 프로그래밍
C++ Classes and Objects

0개의 댓글