Programming Language/C,C++

C, C++] 헤더파일과, CPP파일로 소스 코드 분리

TwinParadox 2017. 7. 4. 00:00
728x90




대학교 학부과정에서 C, C++을 배우는 상황에서는 소스코드를 헤더파일과 CPP(혹은 C, 여기서는 CPP파일로 통칭하겠다.)파일로 분할해서 활용하는 일이 거의 없다. 컴퓨터 사고를 키우는 것과 프로그래밍의 기초에 집중하는 부분도 고려하기 때문인 것도 있지만, 기본적으로 코드를 분할해서 관리할 정도로 코드가 길거나, 재사용할 일이 없기 때문인 것이 가장 크다고 생각한다.


이 글을 쓰면서 헤더파일과 CPP파일 분리를 논하고 있는 본인조차도 학부시절 자료구조 강의를 들을 때가 되어서(아마 연결리스트를 응용하는 함수였던 걸로 기억한다.) 자주 접한 편이었다. 그렇게 강제하거나 따로 배운 건 아니고, 손 하나 대지도 않을 코드를 복사 붙여넣기 해서 괜히 스크롤을 내려야 하는 번거로움에 대한 반항심과 다른 학생들과는 다른 식으로 과제를 제출하겠다는 쓸 데 없는 객기로 인한 행동이었다. 



다시 본론으로 돌아와, 모든 코드를 한 파일에 작성해서 한 파일의 코드가 무지막지하기 길어지는 경우, 또한 다른 곳에서 이 코드를 재사용할 것이라고 생각되는 경우에는 소스코드를 분리할 필요가 있다.

소스코드 분리에서는 두 가지 정도를 고려하여 헤더 파일과 CPP 파일을 작성하는 것이 적절하다.



- 클래스 선언부는 헤더 파일에, 구현부는 CPP에 구분해서 작성한다.

- main 등 함수나 전역 변수도 나누어 작성한다.



간단하게 소스 하나로 분할에 대한 예시에 대해서 다뤄보면 이해가 쉽다.


아래의 코드는 두 개의 피연산자를 입력받아 덧셈 작업을 수행한다.

덧셈 작업을 수행하는 Adder라는 클래스와 계산기 인터페이스를 제공하는 Calculator라는 클래스가 존재하며, 이들을 한 소스파일에 작성하면 아래와 같다.



#include <iostream>
using namespace std;

class Adder
{
private:
	int op1, op2;
public:
	Adder(int a, int b);
	int Process();
};
Adder::Adder(int a, int b)
{
	this->op1 = a;
	this->op2 = b;
}
int Adder::Process()
{
	return this->op1 + this->op2;
}

class Calculator
{
public:
	void Run();
};
void Calculator::Run()
{
	cout << "두 수 입력하시오 : ";
	int a, b;
	cin >> a >> b;
	Adder adder(a, b);
	cout << adder.Process() << endl;
}

int main()
{
	Calculator calc;
	calc.Run();
}



이를 헤더 파일과 CPP파일로 분리하여 작성하면 아래와 같은 모습을 보인다.



main.cpp

#include "Calculator.h"
int main()
{
	Calculator calc;
	calc.Run();
}



Adder.h

#ifndef ADDER_H
#define ADDER_H
class Adder
{
	int op1, op2;
public:
	Adder(int a, int b);
	int Process();
};
#endif



Adder.cpp

#include "Adder.h"
Adder::Adder(int a, int b)
{
	op1 = a;
	op2 = b;
}
int Adder::Process()
{
	return op1 + op2;
}



Calculator.h

#ifndef CALCULATOR_H
#define CALCULATOR_H
class Calculator
{
public:
	void Run();
};
#endif



Calculator.cpp

#include <iostream>
#include "Calculator.h"
#include "Adder.h“
using namespace std;
void Calculator::Run()
{
	cout << "두 개의 수를 입력하시오 : ";
	int a, b;
	cin >> a >> b;
	Adder adder(a, b);
	cout << adder.Process() << endl;
}



위에서 말했듯 이 코드는 구현부를 전부 넣어놓은 소스파일을 선언부와 구현부로 나누는 과정에 대해

익히는 용도로만 설명하기 위해 작성된 코드이기 때문에 번거로울 뿐만 아니라,

여러 과정이 생략되어 있다는 점을 감안하길 바란다.


컴파일러에서는 Calculator.cpp, Adder.cpp, main.cpp를 컴파일해,

각각의 이름으로 된 obj을 생성하고 링크해서 main.exe라는 실행 파일을 생성하게 된다. 

C++ 컴파일러에서는 특히 cpp파일만 컴파일하고 헤더 파일만 따로 컴파일하지는 않는다.


헤더 파일과 CPP 소스 파일로 분리해 사용하는 이유는 전체 프로그램 관리에도 용이하고 재사용에도 용이하기 때문이다. C++에서 소스코드를 이와 같이 분할한 상태에서 이미 작성된 클래스를 활용할 경우, 클래스 선언부를 포함한 헤더 파일을 간단하게 전처리구문으로 포함시키면 된다. 

728x90
728x90