헤더파일과 소스파일
그동안은 코딩테스트를 준비하면서 소스코드를 오직 main.cpp에만 코드를 작성했기 때문에 헤더파일과 소스파일을 구분해서 작성하지 않았던 것 같다. 최근 Class를 활용하여 객체지향 프로그래밍을 본격적으로 공부하면서 헤더파일과 소스파일을 왜 분리하여 사용하면 좋을지 정리하면 좋을 것 같아 글을 작성한다
단순하게 헤더파일과 소스파일을 구분해서 코드를 작성하는 이유는 프로그래밍 중 main.cpp 파일에 모든 소스코드를 작성하면 소스코드가 길어져서 가독성도 떨어질뿐더러, 다른 파일에서 이 코드를 재사용할 때 불편함이 더러 생기게 된다.
이 부분에 대해서는 SOLID 원칙을 정리해 놓은 글을 참고하면 이해가 될 것 같다
객체지향 프로그래밍의 5가지 원칙 - SOLID
SOLID 원칙 개념SOLID 원칙은 객체지향 프로그래밍에서 유지보수성과 확장성을 높이기 위해 적용되는 다섯 가지 주요 설계 원칙으로,로버트 C. 마틴(Robert C. Martin)이 정의하였으며, 마이클 페더스(Mi
bincode.tistory.com
따라서 헤더파일과 소스코드를 분리하여 작성하는데 다음 두 가지 사항은 고려하여 작성하는 것이 바람직하다
- 클래스 선언부는 헤더파일에 작성
- 클래스 구현부는 CPP에 작성
간단하게 소스코드가 main에 하나로 구현되어 있는 코드와 헤더파일과 소스파일이 구분되어 있는 코드를 보면서 확인해 보자
먼저 소스코드가 main에 하나로 구현되어 있는 코드는 아래와 같다
main.cpp에 하나로 구현된 코드
//main.cpp
#include <iostream>
using namespace std;
class Animal{
public:
virtual void makeSound()=0; //순수 가상 함수
~Animal(){};
};
class Dog: public Animal{
public:
void makeSound() override{
cout << "Mung- Mung-\n";
}
};
class Cat: public Animal{
void makeSound() override{
cout << "Aeow- Aeow-\n";
}
};
class Cow: public Animal{
void makeSound() override{
cout << "Moo-\n";
}
};
int main(){
Animal* animal[3];
Dog dog;
Cat cat;
Cow cow;
animal[0] = &dog;
animal[1] = &cat;
animal[2] = &cow;
for(Animal* a : animal){
a->makeSound();
}
return 0;
}
해당 코드는 부모 클래스인 Animal을 자식 클래스인 Dog, Cat, Cow가 상속받아 각 동물의 울음소리를 구현한 뒤, main문에서 for문을 활용하여 Animal 포인터 배열에 저장된 동물들의 울음소리를 출력하는 코드이다
이번에는 Animal 클래스를 헤더파일과 소스파일을 활용하여 코드를 분리해 보겠다
클래스를 헤더파일과 CPP를 활용하여 main파일과 분리한 코드
//Animal.h
#pragma once
#include <iostream>
class Animal {
public:
virtual void makeSound() = 0;
virtual ~Animal() {}
};
class Dog : public Animal {
public:
void makeSound() override;
};
class Cat : public Animal {
public:
void makeSound() override;
};
class Cow : public Animal {
public:
void makeSound() override;
};
Animal.h는 클래스의 선언부만 작성했다
//Animal.cpp
#include "Animal.h"
#include <iostream>
using namespace std;
void Dog::makeSound() {
cout << "Mung- Mung-\n";
}
void Cat::makeSound() {
cout << "Aeow- Aeow-\n";
}
void Cow::makeSound() {
cout << "Moo-\n";
}
Animal.cpp은 클래스의 구현부만 작성했다
//main.cpp
#include <iostream>
#include "Animal.h"
#include "Zoo.h"
using namespace std;
int main() {
Animal* animal[3];
Dog dog;
Cat cat;
Cow cow;
animal[0] = &dog;
animal[1] = &cat;
animal[2] = &cow;
for (Animal* a : animal) a->makeSound();
return 0;
}
main.cpp은 객체 생성과 포인터배열에 들어있는 울음소리를 출력하기 위한 for문만 작성했다
C++에서 소스코드를 이와 같이 나눈 상태에서 이미 작성된 클래스를 활용할 경우, 클래스 선언부를 포함한 헤더 파일을 간단하게 전처리 구문으로 포함하면 재사용하기도 쉬운 상태로 활용될 수 있다
'C++' 카테고리의 다른 글
| [C++] System() 함수 - "cls" , "pause" (0) | 2025.06.13 |
|---|---|
| [C++] 얕은 복사 vs 깊은 복사 (1) | 2025.06.12 |
| [C++] 스마트 포인터(Smart Pointer) 개념 정리 (0) | 2025.06.12 |
| [C++] 헤더파일 중복방지 #Pragma once vs #ifndef ~ endif (0) | 2025.06.10 |
| [C++] String 클래스 정리 및 함수 사용 (0) | 2025.06.04 |