코드 구성
우리는 C++ 코드를 여러 개의 파일로 나눌 수 있습니다. 관례적으로, C++ 소스를 저장하는 두 종류의 파일이 있습니다: 헤더 파일(Headers)과 소스 파일(Source Files).
헤더 파일과 소스 파일
헤더 파일은 주로 다양한 선언을 담는 소스 코드 파일입니다. 헤더 파일은 일반적으로 .h(또는 .hpp) 확장자를 가지고 있습니다. 소스 파일은 정의와 주 프로그램을 저장하는 파일입니다. 일반적으로 .cpp(또는 .cc) 확장자를 가지고 있습니다.
그런 다음 우리는 전처리기 지시문인 #include를 사용하여 헤더 파일을 소스 파일에 포함시킵니다. 표준 라이브러리 헤더를 포함시키기 위해서는 #include 문 뒤에 꺾은 괄호로 둘러싸인 확장자 없는 헤더 이름을 사용합니다. 예를 들어 <headername>과 같습니다.
Example:
#include <iostream>
#include <string>
사용자 정의(user-defined) 헤더 파일을 포함하기 위해 우리는 #include 문을 사용합니다. 그 뒤에는 따옴표로 둘러싸인 확장자가 포함된 전체 헤더 이름이 옵니다.
Example:
#include "myheader.h"
#include "otherheader.h"
현실적인 시나리오는 때로는 표준 라이브러리 헤더와 사용자 정의 헤더 모두를 포함해야 할 필요가 있는 경우입니다.
Example:
#include <iostream>
#include "myheader.h"
컴파일러는 헤더 파일과 소스 파일의 코드를 합쳐서 'translation unit'라고 불리는 것을 생성합니다. 그런 다음 컴파일러는 이 파일을 사용하여 개체 파일을 만듭니다. 링커는 개체 파일을 함께 연결하여 실행 가능한 프로그램이나 라이브러리를 생성합니다. 우리는 선언과 상수를 헤더 파일에 넣고, 정의와 실행 가능한 코드를 소스 파일에 넣어야 합니다.
Header Guards
여러 소스 파일은 동일한 헤더 파일을 포함할 수 있습니다. 우리는 헤더 가드라는 메커니즘을 사용하여 헤더가 컴파일 과정에서 한 번만 포함되도록 합니다. 이는 우리의 헤더 내용이 컴파일 과정에서 한 번만 포함되도록 보장합니다. 우리는 헤더 파일의 코드를 다음 매크로로 감싸줍니다:
#ifndef MY_HEADER_H
#define MY_HEADER_H
// header file source code
// goes here
#endif
이 방법은 헤더 파일 내의 코드가 컴파일 단계에서 한 번만 포함되도록 보장합니다.
Namespaces
지금까지 C++ 코드의 일부를 헤더 파일과 소스 파일로 그룹화하는 방법을 보았습니다. C++ 소스 코드의 일부를 논리적으로 그룹화하는 또 다른 방법이 있습니다. 그것은 네임스페이스(namespaces)를 통한 것입니다. 네임스페이스(namespaces)는 이름을 가진 범위입니다. 네임스페이스(namespaces)를 선언하려면 다음과 같이 작성합니다.
namespace MyNameSpace
{
int x;
double d;
}
이 네임스페이스 밖에서 이러한 객체들을 참조하기 위해 우리는 완전한 경로 이름을 사용합니다. 즉, namespace_name::our_object 표기법을 사용합니다. 다음은 네임스페이스가 선언된 곳 밖에서 객체들을 정의하는 예시입니다.
namespace MyNameSpace
{
int x;
double d;
}
int main()
{
MyNameSpace::x = 123;
MyNameSpace::d = 456.789;
}
현재 범위에 전체 네임스페이스를 도입하기 위해 우리는 using 지시문을 사용할 수 있습니다.
namespace MyNameSpace
{
int x;
double d;
}
using namespace MyNameSpace;
int main()
{
x = 123;
d = 456.789;
}
만약 우리의 코드에 동일한 이름을 가진 여러 개의 별개의 네임스페이스가 있다면, 우리는 해당 네임스페이스를 확장하고 있는 것이며, 재정의하는 것이 아닙니다. 예시:
namespace MyNameSpace
{
int x;
double d;
}
namespace MyNameSpace
{
char c;
bool b;
}
int main()
{
MyNameSpace::x = 123;
MyNameSpace::d = 456.789;
MyNameSpace::c = 'a';
MyNameSpace::b = true;
}
이제 MyNameSpace 네임스페이스 내부에 x, d, c, b가 있습니다. 우리는 MyNameSpace를 확장하고 있는 것이며, 재정의하는 것이 아닙니다. 네임스페이스는 여러 파일에 걸쳐 헤더 파일과 소스 파일 모두에 분산될 수 있습니다. 우리는 종종 프로덕션 코드가 네임스페이스로 둘러싸여 있는 것을 볼 수 있습니다. 이는 코드를 논리적으로 네임스페이스로 그룹화하기 위한 훌륭한 메커니즘입니다.
서로 다른 이름을 가진 두 개의 네임스페이스는 동일한 이름을 가진 객체를 보유할 수 있습니다. 각각의 네임스페이스는 다른 범위이므로 이제 동일한 이름을 가진 두 개의 서로 관련 없는 객체를 선언합니다. 이는 이름 충돌을 방지합니다. 예시:
#include <iostream>
namespace MyNameSpace
{
int x;
}
namespace MySecondNameSpace
{
int x;
}
int main()
{
MyNameSpace::x = 123;
MySecondNameSpace::x = 456;
std::cout << "The 1st x is: " << MyNameSpace::x << ", the 2nd x is: "
<< MySecondNameSpace::x;
}
//The 1st x is: 123, the 2nd x is: 456
'IT > C++' 카테고리의 다른 글
C++ 수명 (Lifetime) (0) | 2023.05.30 |
---|---|
C++ Automatic Type Deduction (auto) (0) | 2023.05.30 |
C++ Strings(c_str() / Substrings) (0) | 2023.05.29 |
C++ References 정리 (0) | 2023.05.28 |
C++이란? (0) | 2023.05.27 |
댓글