C++ 문법(기법) - 2. 헤더파일과 구현파일

Ui Jin·2021년 9월 25일
0

C++ Grammar

목록 보기
9/13

헤더파일과 구현파일

지금까지 만들었던 대부분의 코드들은 비교적 짧았을 것입니다. 하지만 실제로 기업같은곳에서 사용하는 프로그램을 만들기 위해서는 수천줄, 수만줄이 넘는 코드가 사용된다고 합니다. 이렇게 긴 코드들을 관리하기 위해서는 이 소스코드들을 여러 파일로 나누어 관리하는것이 필요하겠죠?

자, 그렇다면 이렇게 여러 파일로 나누기 위해서는 어떻게 해야할까요?
우선 우리의 코드가 실행되는 main()함수가 존재하는 main.cpp의 파일이 있을것입니다. 그리고 이 main.cpp와 같은 디렉토리(폴더)안에 우리가 만든 함수나 구조체 같은 코드들을 담을 파일을 만들어 사용해야 합니다.

이를 위해서, 헤더파일과 구현파일이 존재합니다.
우선 헤더파일은 그 헤더파일을 가져오는 파일에게 사용하고자 하는 것의 존재를 알려주는 역할을 한다고 생각합시다.
구현파일은 이 헤더파일에서 알려준 것이 실제로 구현되어 있는 파일입니다.


#include 전처리

우선 #include전처리는 그 자리에 해당 헤더파일이 있는것처럼 작동하도록 합니다.

즉, #include <iostream> 이란 코드는 이 자리에 해당 iostream이 있는것처럼 작동하도록 도와줍니다.

"이 자리에"라는 말을 기억해주셨으면 좋겠습니다.

  • 이 말인 즉슨 전처리의 순서가 중요하다는 것입니다. 만약 a라는 파일에서 b파일에 정의된 내용을 사용한다고 가정해 봅시다. 이 때 b를 먼저 불러오지 않고, a를 불러오게되면 이 a는 b의 존재를 모르고 있기 때문에 오류를 일으키게 됩니다.
  • 또 같은 이름의 함수 void testa(int a);를 가지고 있는 헤더 파일이 a, b두개가 있다고 가정해 봅시다. 이 때 main.cpp파일에서 이 두 파일을 #include한 후에 testa()함수를 사용한다면, 이 함수가 a에있는 함수인지, b에 있는 함수인지 판단할 방법이 없으므로 오류를 일으키게 됩니다.
  • 또 같은 헤더파일을 두번 #include할 경우 중복정의가 되므로 오류를 일으키게 됩니다.

이렇게 #include 를 통해 사용하고자하는 함수의 원형(prototype)이 있는 헤더파일을 불러오면, 컴퓨터는 "아, 이러한 함수가 있구나"라고 생각하게 되고 후에 이 함수를 사용할 때, 그 함수의 내용을 .cpp 파일들에서 찾아보게되고 실행할 수 있게 됩니다.

  • 참고: #include < > 와, #include " "의 차이
    <>를 사용하는 경우 표준 라이브러리의 헤더파일이 위치한 폴더에서 파일을 찾게 됩니다.
    반면에 ""를 사용하는 경우에는 현재 소스파일이 있는 위치에서 해당 파일을 찾게 됩니다.

헤더파일

1) 파일명

  • 확장자: .h
  • 파일이름: 구현파일
    (파일이름을 구현파일과 같이 하는것은 후에 헷갈리지 않도록 하기 위한 권장사항 입니다.)
  • 예시: point.h

2) 파일 내용

  • 중복방지 심볼

소스파일이 아주 많아지면 파일간의 포함관계가 복잡해질 수 있습니다.

이때 같은 헤더파일을 두번 포함하는 경우가 생길 수 있는데 이 경우 위에서 설명한 이유로 인해 오류를 일으키게 됩니다.

이를 방지하기 위해 다음의 방법이 있습니다.

#ifndef POINT_H			// 해석: if not define POINT_H, 
				// 즉, 만약 POINT_H심볼이 정의되어 있지 않으면
#define POINT_H			// 해석: define POINT_H 
				// 즉, POINT_H 심볼을 정의한다.

#endif

(비쥬얼 스튜디오의 경우 같은 역할을 하는 다음의 전처리기를 지원합니다.)

#pragma once
  • 함수의 프로토 타입
double distance(point& x, point& y);
  • 구조체의 정의
struct point {
   int x, y;
}

3) 예시

파일이름: point.h

파일내용

#ifndef POINT_H
#define POINT_H

struct point {
  int x, y;
};

double distance(point& x, point& y);

#endif

4) 주의사항

헤더파일에는 inline함수만 존재해야 합니다.

참고로 class의 멤버 함수들은 inline으로 작동합니다.

<< 연산자 오버로딩을 할 때 이로인해서 작동되지 않는 경우가 존재합니다.


구현파일

1) 파일명

  • 확장자: .cpp
  • 파일 이름: 구현파일
    (구현파일의 이름은 이 파일안에 담긴 내용을 대표할 수 있는 단어로 하는것이 좋겠죠)
  • 예시: point.cpp

2) 파일내용

  • 전처리

구현에 필요한 파일들을 미리 전처리하여 가져옵니다.

#include <iostream>		// 사용할 헤더파일
#include "abcd.h"		// 사용할 헤더파일
#include "point.h"		// 자기 자신의 헤더파일

(이 때 이 구현파일 안의 함수가 서로 호출할 경우 그 순서에 따라 문제가 발생할 수 있습니다. 이를 방지하기 위해서 자기 자신의 헤더파일을 #include해주는 것이 좋습니다.)

  • 함수 구현

이제 헤더파일에서 정의한 프로토 타입 함수들을 구현해 줍시다.

double distance (point& x, point& y) {
	~ 
}

3) 예시

파일이름: point.cpp

파일 내용

#include <iostream>
#include <cmath>
#include "point.h"

double distance(point& x, point& y) {

  함수 내용

}

자 마지막으로 정리해 보면 헤더파일에는

  • 구조체
  • 함수의 prototype
  • class의 정의(멤버함수의 prototype만 존재)

그리고 구현파일에는

  • 함수의 구현
  • class의 멤버함수의 원형

이 들어가게 될 것입니다.

profile
github로 이전 중... (https://uijinee.github.io/)

0개의 댓글