microsoft visual studio를 이용한 파일 분할 방법을 알아보겠다.
파일 분할이란 긴 코드를 작게 나누어 여러 개의 파일로 저장하는 방법이다. 어떠한 프로그램이건 하나의 파일에 모든 것을 담진 않는다. C++도 클래스 별로 헤더 파일과 소스파일을 생성해서 클래스의 선언과 정의를 분리한다.
파일 분할을 하는 이유는 다음과 같다.
- 긴 코드를 작은 단위로 나눠 가독성을 높게한다.
- 선언부와 정의부를 분리시켜 코드의 재사용을 가능하게 한다.
공부한 책의 예제를 사진 캡처와 함께 사용법을 공유하겠다.
분할을 하기 전 코드 전체를 보도록 하자.
#include <iostream>
#include <cstring>
using namespace std;
namespace CAR_CONST {
enum {
ID_LEN = 20, MAX_SPD = 200, FUEL_STEP = 2,
ACC_STEP = 10, BRK_STEP = 10
};
}
class Car {
private:
char gamerID[CAR_CONST::ID_LEN];
int fuelGauge;
int curSpeed;
public:
void InitMembers(const char * ID, int fuel);
void ShowCarState();
void Accel();
void Break();
};
void Car::InitMembers(const char *ID, int fuel) {
strcpy(gamerID, ID); # 비주얼 스튜디오에선 strcpy_s를 사용하자.
fuelGauge = fuel;
curSpeed = 0;
}
void Car::ShowCarState() {
cout << "소유자ID: " << gamerID << endl;
cout << "연료량: " << fuelGauge << "%" << endl;
cout << "현재속도: " << curSpeed << "km/s" << endl << endl;
}
void Car::Accel() {
if(fuelGauge <= 0) return;
else fuelGauge -= CAR_CONST::FUEL_STEP;
if((curSpeed+CAR_CONST::ACC_STEP)>= CAR_CONST::MAX_SPD) {
curSpeed = CAR_CONST::MAX_SPD;
return;
}
curSpeed += CAR_CONST::ACC_STEP;
}
void Car::Break() {
if(curSpeed<CAR_CONST::BRK_STEP) {
curSpeed = 0;
return;
}
curSpeed -= CAR_CONST::BRK_STEP;
}
int main() {
Car run99;
run99.InitMembers("run99", 100);
run99.Accel();
run99.Accel();
run99.Accel();
run99.ShowCarState();
run99.Break();
run99.ShowCarState();
return 0;
}
실행 결과는 이렇다.
소유자ID: run99
연료량: 94%
현재속도: 30km/s
소유자ID: run99
연료량: 94%
현재속도: 20km/s
그럼 이제 이 긴 코드를 작게 분할하는 방법을 알아보자.
필자는 visual studio 2022 버전을 사용했다.
파일을 분할할 때는 3개의 파일로 나눈다. 헤더 파일, 소스파일, main함수가 있는 파일 헤더 파일과 소스파일의 의미는 다음과 같다.
- Car.h - 클래스의 선언을 담는다.
- Car.cpp - 클래스의 정의(멤버 함수의 정의)를 담는다.
클래스의 선언이란 C++ 컴파일러가 클래스에 대한 정보를 알게 하는 최소한의 정보를 의미한다. 클래스의 기본 틀 안에 멤버 변수와 멤버 함수의 선언 부만을 적는 것이다. 그리고 파일 종류는 헤더(. h)로 한다.
클래스의 정의란 선언된 클래스 안에 비어있는 멤버 함수의 성질을 정의하는 것이다. 정의를 다른 파일에 함으로써 코드의 재사용성을 높일 수 있다.
이제 비주얼 스튜디오에서 어떻게 위의 긴 코드를 분할하는지 알아보자.
1단계: 소스파일과 헤더 파일, main() 파일 생성
먼저 비주얼 스튜디오를 시작한다.
빈 프로젝트를 선택하고
1. 소스파일을 생성
사진과 같은 방법으로 소스파일을 추가하자.
Car.cpp로 소스파일 이름을 설정한다.
2. 헤더 파일 생성
사진과 같은 방법으로 헤더 파일을 추가하자.
헤더 파일을 클릭하고 이름은 Car.h로 설정하자.
3. main() 파일 생성
사진에 따라 main() 파일을 생성한다.
이제 1단계가 끝났다. 이렇게 파일 분할은 소스파일.cpp, 헤더 파일.h, main파일.cpp 세 개로 나눠진다.
2단계: 내용 입력하기
앞에서 소스파일은 클래스의 비어있는 멤버 함수를 정의하는 거라고 했다. 하지만 그냥 옮겨 적기만 하면 비주얼 스튜디오가 알아서 인식하는 건 아니고 추가로 적어줘야 할 것이 있다.
1. 헤더 파일 옮기기
일단 헤더 파일부터 보도록 하자.
// #ifndef __CAR_H__
// #define __CAR_H__
#pragma once
// 함수를 선언하는 곳.
namespace CAR_CONST {
enum {
ID_LEN = 20, MAX_SPD = 200, FUEL_STEP = 2,
ACC_STEP = 10, BRK_STEP = 10
};
}
class Car {
private:
char gamerID[CAR_CONST::ID_LEN];
int fuelGauge;
int curSpeed;
public:
void InitMembers(const char* ID, int fuel);
void ShowCarState();
void Accel();
void Break();
};
// #endif
(Car.h파일인 헤더 파일에 옮겨 줘야 한다.)
멤버 변수와 멤버 함수의 선언을 포함한 기본적인 클래스의 틀을 적었다. 그리고 #pragma once를 맨 위 줄에 적었다.
#pragma once는 헤더 파일의 충돌을 막기 위해서 반드시 적어줘야 하는 코드다.
그리고 주석 처리한 #ifndef ~ #define ~ #endif 코드를 한 줄로 대체할 수 있어 매우 간편하다.
하지만, 옛 버전의 비주얼 스튜디오에서는 지원하지 않는다고 하니 비교적 최신 버전에서만 사용 가능하다는 점을 알아야 한다.
실행한 후에 모습은 다음과 같다.
2. 소스파일 옮기기
#include<iostream>
#include<cstring>
#include "Car.h"
// Car.h에서 선언한 함수들을 정의하는 곳.
using namespace std;
void Car::InitMembers(const char* ID, int fuel) {
strcpy_s(gamerID, ID);
fuelGauge = fuel;
curSpeed = 0;
}
void Car::ShowCarState() {
cout << "소유자ID: " << gamerID << endl;
cout << "연료량: " << fuelGauge << "%" << endl;
cout << "현재속도" << curSpeed << "km/s" << endl << endl;
}
void Car::Accel() {
if (fuelGauge <= 0) return;
else {
fuelGauge -= CAR_CONST::FUEL_STEP;
}
if ((curSpeed + CAR_CONST::ACC_STEP) >= CAR_CONST::MAX_SPD) {
curSpeed = CAR_CONST::MAX_SPD;
return;
}
curSpeed += CAR_CONST::ACC_STEP;
}
void Car::Break() {
if (curSpeed < CAR_CONST::BRK_STEP) {
curSpeed = 0;
return;
}
curSpeed -= CAR_CONST::BRK_STEP;
}
Car.cpp 소스파일에 함수의 정의 부분을 옮겨왔다. 단, 소스파일은 정의 부분만 존재하므로 함수를 선언해준 헤더 파일을 포함한다는 코드를 적어줘야 한다. 그래서 3줄에 #include "Car.h"를 따로 적어줬다.
소스파일에 헤더 파일을 추가하는 방식은 다음과 같다.
-> #include "헤더 파일 이름"
보이는 것처럼 간단하다.
함수 ShowCarState 에서 cout으로 출력하는 함수가 있으므로 #include<iostream>과 using namespace std; 도 추가해 준다.
위 코드에선 strcpy_s도 있으니 #include<cstring> 도 추가한 것을 볼 수 있다.
실행 후 모습은 아래와 같다.
3. main() 파일 옮기기
#include "Car.h"
int main() {
Car run99;
run99.InitMembers("run99", 100);
run99.Accel();
run99.Accel();
run99.Accel();
run99.ShowCarState();
run99.Break();
run99.ShowCarState();
return 0;
}
main() 함수가 존재하는 파일이다. 함수 안에 클래스로 객체 생성하고, 멤버 함수 호출하는 등의 명령이 적혀있다.
여기서도 헤더 파일을 추가해 줘서 Car 클래스가 무엇인지 알려주기 위해 #include "Car.h"를 추가해 준다.
실행 후 모습은 아래와 같다.
3단계: 실행하기
올바르게 옮겼다면 Ctrl + F5 키를 눌러 실행하면 다음 사진과 같이 실행이 된다.
긴 파일을 분할하여 작은 파일 여러 개로 만드는 과정을 알아보았다.
다음 포스팅에는 2개의 클래스를 분할하는 방법에 대해 적도록 하겠다.
http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&ejkGb=KOR&barcode=9788996094043
'[Computer Science] > [C & C++]' 카테고리의 다른 글
[C/C++] const의 위치에 따른 의미 정리 (0) | 2022.04.20 |
---|---|
2개 이상의 class 파일 분할 (0) | 2022.03.24 |