프로그래밍 언어/C++

C++ inline - 7. 클래스 내에서의 inline 함수

개발_노트 2025. 3. 27. 18:25

7. 클래스 내에서의 inline 함수

C++에서는 클래스 내부에서 정의된 멤버 함수는 자동으로 inline 함수로 처리됩니다.
따라서, 별도로 inline 키워드를 명시하지 않아도, 컴파일러는 해당 함수를 인라인 확장(Inline Expansion) 대상으로 고려합니다.


🔹 클래스 멤버 함수의 암시적 inline

암시적 inline이란?

  • 클래스 내부에서 정의된 멤버 함수는 inline 키워드를 명시하지 않아도 자동으로 inline으로 간주됩니다.
  • 하지만, 컴파일러가 판단하여 반드시 inline을 적용하는 것은 아님.
  • 너무 큰 함수나 루프가 포함된 함수는 자동 인라인 확장이 거부될 가능성이 높음.

암시적 inline 예제

#include <iostream>

class Math {
public:
    int add(int a, int b) {  // 클래스 내부에서 정의 → 암시적 inline
        return a + b;
    }
};

int main() {
    Math math;
    std::cout << math.add(3, 4) << std::endl;  // 함수 호출 없이 직접 연산될 가능성이 높음
    return 0;
}

📌 위 코드에서 add(int a, int b)는 inline 키워드를 명시하지 않아도 inline으로 간주됨

  • 클래스 내부에서 직접 정의되었으므로 암시적으로 inline이 적용됨.
  • 그러나, 컴파일러가 최적화 과정에서 반드시 inline 확장을 수행하는 것은 아님.

암시적 inline이 거부될 가능성이 있는 경우

class Math {
public:
    int complexOperation(int a, int b) {  // 함수 크기가 커서 inline 확장 거부 가능성 높음
        int result = 0;
        for (int i = 0; i < 100; i++) {
            result += (a * i + b);
        }
        return result;
    }
};

📌 이 함수는 루프가 포함되어 있어 inline 확장이 거부될 가능성이 큼

  • 컴파일러는 함수 크기가 너무 크거나 반복문이 많으면 inline 확장을 수행하지 않을 수 있음.
  • 큰 함수는 따로 cpp 파일에서 정의하는 것이 바람직함.

🔹 헤더 파일에서 정의된 멤버 함수

헤더 파일에서 정의할 때 inline이 필요한 이유

일반적으로 클래스 멤버 함수를 헤더 파일에서 정의하면 여러 소스 파일에서 포함될 수 있음.
그러나, C++에서 동일한 함수가 여러 번 정의되면 링커 오류(Linker Error)가 발생할 수 있음.
이 문제를 방지하기 위해, 헤더 파일에서 정의된 함수에는 inline 키워드를 명시하는 것이 권장됨.


헤더 파일에서 inline 사용 예제

📁 math_utils.h

#ifndef MATH_UTILS_H
#define MATH_UTILS_H

class Math {
public:
    inline int add(int a, int b) {  // 명시적 inline
        return a + b;
    }

    inline int multiply(int a, int b) {
        return a * b;
    }
};

#endif // MATH_UTILS_H

📁 main.cpp

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

int main() {
    Math math;
    std::cout << math.add(3, 4) << std::endl;
    std::cout << math.multiply(5, 6) << std::endl;
    return 0;
}

📌 이렇게 하면?

  • math_utils.h를 여러 소스 파일에서 포함하더라도 링커 오류 없이 컴파일 가능.
  • inline을 사용하지 않으면 다른 소스 파일에서 포함될 때 중복 정의 오류가 발생할 수 있음.

헤더 파일에서 inline을 사용하지 않으면 발생하는 문제점

📁 math_utils.h (잘못된 예)

#ifndef MATH_UTILS_H
#define MATH_UTILS_H

class Math {
public:
    int add(int a, int b);  // 선언만 존재
};

#endif // MATH_UTILS_H

📁 math_utils.cpp

#include "math_utils.h"

int Math::add(int a, int b) {  // 함수 정의
    return a + b;
}

📁 main.cpp

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

int main() {
    Math math;
    std::cout << math.add(3, 4) << std::endl;
    return 0;
}

📌 이 경우 math_utils.cpp가 포함되지 않으면 링크 오류 발생

  • add(int, int)의 정의가 포함되지 않아 컴파일 시 "undefined reference" 오류 발생.
  • 이런 경우, 함수를 math_utils.cpp에 정의하는 것이 올바른 해결책.
  • 그러나, 헤더 파일에서 정의하고 싶다면 inline을 명시하는 것이 안전함.

🔹 클래스 내 inline과 cpp 파일에서 정의하는 방법 비교

정의 방식 장점 단점
클래스 내부 정의 (암시적 inline) 코드가 간결해지고 가독성이 좋음 코드 크기가 증가할 가능성 있음
헤더 파일에서 inline 사용 링커 오류 방지, 재사용 가능 많은 코드가 포함되면 컴파일 시간 증가
cpp 파일에서 정의 코드 크기 증가 방지, 모듈화 용이 함수 호출 오버헤드 존재

📌 결론
짧고 간단한 함수클래스 내부에서 정의하여 inline 적용
헤더 파일에서 멤버 함수를 정의할 경우 inline을 명시적으로 사용하여 링커 오류 방지
큰 함수는 cpp 파일에서 정의하여 코드 크기를 줄이고, 컴파일 시간을 최적화


📌 정리

클래스 내부에서 정의된 멤버 함수는 inline이 자동으로 적용됨 (암시적 inline)
컴파일러가 반드시 inline 확장을 수행하는 것은 아니며, 최적화 여부에 따라 결정됨
헤더 파일에서 멤버 함수를 정의하면 inline 키워드를 사용하여 링커 오류를 방지해야 함
크기가 큰 함수는 cpp 파일에서 정의하는 것이 바람직함

📌 결론
작은 함수는 inline을 활용하여 성능을 최적화할 수 있지만, 남용하면 코드 크기가 증가하고 컴파일 시간이 길어질 수 있으므로 신중하게 사용해야 합니다!