[C++] 기본 Syntax 2
파일 분할
//main.cpp
# include <iostream>
int num = 0;
//------------------------------------------------------------------임의의 위치에서 파일 분할
void Increment(void) {
	num++;
}
int GetNum(void) {
	return  num;
}
//------------------------------------------------------------------임의의 위치에서 파일 분할
int main(void) {
	std::cout << GetNum() << std::endl;
	using namespace std;
	Increment();
	cout << GetNum() << endl;
	return 0;
}
- 주석에서 명시한 위치에서와 같이 임의의 위치에서 파일 분할을 하면(include 문을 제대로 써도) 컴파일 에러가 발생한다.
 - 컴파일러는 파일 단위로 컴파일을 진행하기 때문이다. 따라서 변수의 선언을 못찾을 수도, 함수의 선언을 못찾을 수도 있다.
 
extern int num;
extern void Increment(void);
void Increment(void);
- int형 변수 num이 외부에 선언되어있음을 알린다.
 - Increment 함수가 외부에 선언되어있음을 알린다.
 - 함수의 경우 extern 선언을 생략할 수 있다.
 
static
- 이 변수는 외부 파일에서 접근을 허용하지 않는다. 라는 의미
 - 혹은 이 변수의 접근 범위는 파일 내부로 제한한다. 라는 의미
 
//main.cpp
# include <iostream>
using namespace std;
extern void Increment();
extern int GetNum();
static void SimpleFunc() {
	cout << "main 에서만 사용할 함수" << endl;
}
int main(void) {
	std::cout << GetNum() << std::endl;
	using namespace std;
	Increment();
	cout << GetNum() << endl;
	SimpleFunc();
	return 0;
}
 //func.cpp
extern int num;
void Increment(void) {
	num++;
}
int GetNum(void) {
	return  num;
}
 //num.cpp
int num = 0;
헤더파일의 디자인과 활용
//header1.h
{ 
	std::cout << "123" << endl;
 //header2.h
}
int main(void) 
#include "header1.h"
#include "header2.h"
- 위 프로그램은 정상적으로 작동이 된다.
 - “#include”의 뜻은 이 문장의 위치에다가 header.h에 저장된 내용을 가져다 놓으세요.이다.
 - “#include” 지시자는 그 이름이 의미하듯이 파일의 내용을 단순히 포함시키는 용도로 사용된다. 그 이상 그 이하도 아닌 단순한 ‘포함’을 의미한다.
 
“#include” <헤더파일 이름=""> v.s. "#include" "헤더파일 이름"헤더파일>
- 첫 번째 방식 : #include <헤더파일 이름="">
헤더파일>    
- 표준 헤더파일(C의 표준에서 정의하고 있는, 기본적으로 제공되는 헤더파일)이 저장되어 있는 디렉터리에서 파일을 찾게 된다. 때문에 이 방식은 
과 같은 표준 헤더파일을 포함시킬 경우 사용한다.  
 - 표준 헤더파일(C의 표준에서 정의하고 있는, 기본적으로 제공되는 헤더파일)이 저장되어 있는 디렉터리에서 파일을 찾게 된다. 때문에 이 방식은 
 - 두 번째 방식 : #include “헤더파일 이름”
    
- 이 문장을 포함하는 소스파일이 저장된 디렉터리에서 헤더파일을 찾는다. 즉, 프로그래머가 정의하는 헤더파일을 포함시킬 때 사용하는 방식이다.
 
 - 두 번째 방식을 사용하면 절대경로를 사용해서 헤더파일을 지정할 수 있다.
    
- $#include ‘C:\niklasjang\document\cpp\header.h”$
 
 - 두 번째 방식을 사용해서 상대경로를 사용해서 헤더파일을 지정할 수 있다.
    
- $#include “Release\header0.h”$ 소스파일이 있는 디렉터리의 하위 디렉터리인 Release 디렉터리에 존재하는 header0.h를 include
 - $#include “..\Release\header0.h”$ 한 단계 상위 디렉터리의 하위 디렉터리인 Release 디렉터리에 존재하는 header0.h를 include
 - $#include “....\Release\header0.h”$ 두 단계 상위 디렉터리의 하위 디렉터리인 Release 디렉터리에 존재하는 header0.h를 include
 
 
헤더파일에 어떤 파일을 넣을 것인가?
extern int num;
extern int GetNum(void);
- 외부에 선언된 변수나 함수에 접근하기 위해서 필요한 선언들이지만 매번 삽입하는 것은 번거로우니 이들 선언을 헤더파일에 모아두고 필요할 때마다 헤더파일을 포함시키는 방법을 선택한다.
 
//header.h
#pragma once
#define PI 3.1415
double Add(double num1, double num2);
double Min(double num1, double num2);
double Mul(double num1, double num2);
double Div(double num1, double num2);
 //main.cpp
#include<iostream>
#include "header.h"
int main(void) {
	Add(10, 20);
	return 0;
}
double Add(double num1, double num2) {
	return num1 + num2;
}
double Min(double num1, double num2) {
	return num1 - num2;
}
double Mul(double num1, double num2) {
	return num1 * num2;
}
double Div(double num1, double num2) {
	return num1 / num2;
}
- 매크로 PI에 대한 정의가 헤더파일 header.h에 삽입되어있다. 때문에 PI를 필요로 하는 소스 파일은 header.h를 포함시키기만 하면 된다.
 - 구조체의 정의도 헤더파일에서 작성하고, 구조체를 여러 개의 소스 파일에서 사용하도록 한다.
 - class 정의 과정에서 .h 파일과 .cpp파일의 사용 방법 그리고 여러개의 cpp 파일을 한꺼번에 컴파일 하는 방법은 아래 예제를 참고한다.
 
파일 분할 예제
#pragma once
//PointHeader.h
#ifndef __POINT_H__
#define __POINT_H__
class Point {
private:
	int x;
	int y;
public:
	bool InitMembers(int xpos, int ypos);
	int GetX() const;
	int GetY() const;
	bool SetX(int xpos);
	bool SetY(int ypos);
};
#endif
#pragma once
//RectangleHeader.h
#ifndef __RECTANGELHEADER_H__
#define __RECTANGELHEADER_H__
#include "PointHeader.h"
class Rectangle {
private:
	Point upLeft;
	Point lowRight;
public:
	bool InitMembers(const Point &ul, const Point &lr);
	void ShowRecInfo() const;
};
#endif
//point.cpp
#include <iostream>
#include "PointHeader.h"
using namespace std;
bool Point::InitMembers(int xpos, int ypos) {
	if (xpos < 0 || ypos < 0) {
		cout << "position under Zero Error" << endl;
		return false;
	}
	x = xpos;
	y = ypos;
	return true;
}
int Point::GetX() const {
	return x;
}
int Point::GetY() const {
	return y;
}
bool Point::SetX(int xpos) {
	if (xpos < 0 || xpos > 100) {
		cout << "position under Zero Error" << endl;
		return false;
	}
	x = xpos;
	return true;
}
bool Point::SetY(int ypos) {
	if (ypos < 0 || ypos > 100) {
		cout << "position under Zero Error" << endl;
		return false;
	}
	y = ypos;
	return true;
}
//Rectangle.cpp
#include <iostream>
#include "RectangleHeader.h"
using namespace std;
bool Rectangle::InitMembers(const Point &ul, const Point &lr) {
	if (ul.GetX() > lr.GetX() || ul.GetY() < lr.GetY()) {
		cout << "Postioin Error!" << endl;
		return false;
	}
	upLeft = ul;
	lowRight = lr;
	return true;
}
void Rectangle::ShowRecInfo() const {
	cout << "좌 상단 : " << '[' << upLeft.GetX() << ",";
	cout << upLeft.GetY() << ']' << endl;
	cout << "우 하단: " << '[' << lowRight.GetX() << ",";
	cout << lowRight.GetY() << ']' << endl;
}
//main.cpp
#include <iostream>
#include "PointHeader.h"
#include "RectangleHeader.h"
using namespace std;
int main(void) {
	Point pos1;
	if (!pos1.InitMembers(-2, 10)) {
		cout << "초기화 실패" << endl;
	}
	if (!pos1.InitMembers(2, 10)) {
		cout << "초기화 실패" << endl;
	}
	Point pos2;
	if (!pos2.InitMembers(6, 5)) {
		cout << "초기화 실패" << endl;
	}
	Rectangle rec1;
	if (!rec1.InitMembers(pos1, pos2)) {
		cout << "초기화 실패" << endl;
	}
	rec1.ShowRecInfo();
	return 0;
}
[출처] 두 객체의 결합 : Point, Rectangel|작성자 niklasjang