[ Effective C++ ] 정리 모음집
" C++ 프로그래머의 필독서, 스콧 마이어스의 Effective C++ 를 읽고 내용 요약 / 정리 "
" 인라인 함수는 아무리 생각해도 훌륭한 아이디어! 그렇기에 더 제대로 알아두자! "
- 함수 인라인은 작고, 자주 호출되는 함수에 대해서만 하는 것으로 묶어두자!
- 함수 템플릿이 대개 헤더 파일에 들어간다는 일반적인 부분만 생각해서 이들을 inline으로 선언하면 안된다!
함수처럼 보이고 함수처럼 동작
매크로 보다 훨씬 안전하고 쓰기 좋다
- [ 항목 2 : #define을 쓰려거든 const, enum, inline을 떠올리자 ] 참조
함수 호출 시 발생하는 오버헤드도 걱정할 필요 없다
사용 시 컴파일러가 함수 본문에 대해 문맥별 최적화를 걸기가 용이해진다
- 대체적으로 컴파일러 최적화는 함수 호출이 없는 코드가 연속적으로 이어지는 구간에 적용되도록 설계되었기 때문
목적 코드의 크기가 커질 수 있다
- 메모리가 제한된 컴퓨터에서 인라인 함수를 남발했다간 프로그램 크기가 정해진 공간의 크기를 넘어버릴 수 있다
- 가상 메모리를 쓰는 환경일지라도 성능의 걸림돌이 될 수 있다.
페이징 횟수가 늘어나고, 명령어 캐시 적중률이 떨어질 가능성도 높아진다
반대의 경우(본문 길이가 굉장히 짧은 경우) 상황이 바뀐다는 것도 기억하자
inline은 컴파일러에게 '명령'을 하는 것이 아닌 '요청'을 하는 것!
암시적, 명시적 방법이 있다
class Person
{
public:
...
int age() const { return theAge;}
...
private:
int theAge;
};
클래스 정의 안에 함수를 바로 정의해 넣으면 컴파일러는 그 함수를 인라인 함수 후보로 찍는다
대개 멤버 함수 이지만 프렌드 함수로 클래스 내부에서 정의 될 수 있음
template<typename T>
inline const T& max(const T& a, const T& b)
{ return a < b ? b : a; }
루프가 들어있거나 재귀 함수인 경우
가상 함수를 호출한 경우
- virtual과 inline 둘의 의미만 보아도 말이 안된다.
- virtual의 의미 : 어떤 함수를 호출 할지 결정하는 작업을 실행 중에 한다
- inline의 의미 : 함수 호출 위치에 호출된 함수를 끼워 넣는 작업을 프로그램 실행 전에 한다
inline void f() { ... } // 인라인 함수
void (*pf) () = f; // f를 가리키는 함수 포인터
...
f(); // 인라인 성공
pf(); // 함수 포인터를 통한 호출 이므로 인라인 실패
📢 함수 포인터를 사용하지 않아도 생기는 문제
[ 예시 코드 ]
class Base
{
private:
std::string bm1, bm2;
};
class Derived: public Base
{
public:
Derived() {}
private:
std::string dm1, dm2, dm3;
};
[ 동작 방식 유추 ]
class Derived: public Base
{
public:
Derived()
{
Base::Base();
try { dm1.std::string::string(); } // dm1 생성 도중 예외를 던지면?
catch (...) // 기본 클래스 부분 소멸 후 예외 전파
{
Base::~Base();
throw;
}
// dm2, dm3 에 대해서도 위와 동일
}
private:
std::string dm1, dm2, dm3;
};