Ver3.0 ๐ C++20 ๋ชจ๋๋ก ๋๊ท๋ชจ ํ๋ก์ ํธ๋ฅผ ๊น๋ํ๊ฒ ๊ตฌ์กฐํํ๋ ์๋ฒฝ ๊ฐ์ด๋

๐ C++20 ๋ชจ๋๋ก ๋๊ท๋ชจ ํ๋ก์ ํธ๋ฅผ ๊น๋ํ๊ฒ ๊ตฌ์กฐํํ๋ ์๋ฒฝ ๊ฐ์ด๋
์ปดํ์ผ ์๊ฐ์ ์ค์ด๊ณ , ์ฝ๋ ๊ด๋ฆฌ๋ ์ฝ๊ฒ! ๋ชจ๋ C++์ ๊ฒ์ ์ฒด์ธ์ ๋ฅผ ๋ง๋๋ณด์ ๐ก
์๋
! ๐ ํน์ ๋๊ท๋ชจ C++ ํ๋ก์ ํธ์์ ํค๋ ํ์ผ ์ง์ฅ์ ๊ฒฝํํด๋ณธ ์ ์์ด? ์๋ฐฑ ๊ฐ์ #include ๋ฌธ์ ๊ด๋ฆฌํ๋ค๊ฐ ์ํ ์์กด์ฑ ์๋ฌ์ ๋จธ๋ฆฌ๋ฅผ ์ฅ์ด๋ฏ๊ฑฐ๋, ๋จ ํ ์ค ์์ ํ๋๋ฐ ํ๋ก์ ํธ ์ ์ฒด๊ฐ ์ฌ์ปดํ์ผ๋๋ ์
๋ชฝ ๋ง์ด์ผ. ๐ฑ
์ค๋์ ๊ทธ๋ฐ ๊ณ ๋ฏผ์ ํ ๋ฐฉ์ ๋ ๋ ค์ค C++20 ๋ชจ๋(Modules)์ ๋ํด ์ด์ผ๊ธฐํด๋ณผ ๊ฑฐ์ผ. ์ด๊ฑด ๋จ์ํ ๊ธฐ๋ฅ ์ถ๊ฐ๊ฐ ์๋๋ผ, C++ ํ๋ก๊ทธ๋๋ฐ ํจ๋ฌ๋ค์์ ์์ ํ ๋ฐ๊ฟ๋์ ํ๋ช
์ ์ธ ๋ณํ๋ผ๊ณ ํ ์ ์์ด!
์ค์ ๋ก ์ฌ๋ฅ๋ท ๊ฐ์ ํ๋ซํผ์์๋ C++ ๋ชจ๋ ๊ด๋ จ ์ปจ์คํ
์ด๋ ์ฝ๋ ๋ฆฌํฉํ ๋ง ์ฌ๋ฅ์ด ์ ์ ์ธ๊ธฐ๋ฅผ ์ป๊ณ ์๋ค๊ณ ํ๋๋ผ๊ณ . ๊ทธ๋งํผ ์ค๋ฌด์์๋ ์ฃผ๋ชฉ๋ฐ๊ณ ์๋ค๋ ์ฆ๊ฑฐ์ง! ๐ฅ
๐ฏ C++20 ๋ชจ๋, ๋๋์ฒด ๋ญ๊ฐ ๋ค๋ฅธ ๊ฑฐ์ผ?
์, ๋จผ์ ๊ธฐ๋ณธ๋ถํฐ ์ง๊ณ ๋์ด๊ฐ์. C++20 ์ด์ ๊น์ง๋ ์ฝ๋๋ฅผ ์ฌ์ฌ์ฉํ๋ ค๋ฉด ํค๋ ํ์ผ(.h)๊ณผ ๊ตฌํ ํ์ผ(.cpp)๋ก ๋๋ ์ ์์ฑํ์ด. ๊ทธ๋ฆฌ๊ณ ํ์ํ ๊ณณ์์ #include๋ก ๊ฐ์ ธ๋ค ์ผ์ง.
๋ฌธ์ ๋ ์ด ๋ฐฉ์์ด ํ
์คํธ ๊ธฐ๋ฐ ๋ณต์ฌ-๋ถ์ฌ๋ฃ๊ธฐ๋ผ๋ ๊ฑฐ์ผ. ์ปดํ์ผ๋ฌ๋ #include๋ฅผ ๋ง๋๋ฉด ๊ทธ๋ฅ ํด๋น ํ์ผ์ ๋ด์ฉ์ ํต์งธ๋ก ๋ณต์ฌํด์ ๋ถ์ฌ๋ฃ์ด. ๐
์์ํด๋ด. 100๊ฐ์ ์์ค ํ์ผ์ด ๊ฐ์ ํค๋๋ฅผ includeํ๋ฉด? ๊ทธ ํค๋์ ๋ด์ฉ์ด 100๋ฒ ํ์ฑ๋๊ณ , 100๋ฒ ์ปดํ์ผ๋ผ. ์์ฒญ๋ ๋ญ๋น์ง!
๐ ์ ํต์ ์ธ ํค๋ ๋ฐฉ์์ ๋ฌธ์ ์
1. ์ปดํ์ผ ์๊ฐ ํญ๋ฐ โฐ
๋ํ ํ๋ก์ ํธ์์๋ ๋จ์ํ ํค๋ ํ๋ ์์ ํด๋ ์์ญ ๋ถ์ฉ ์ปดํ์ผ ์๊ฐ์ด ๊ฑธ๋ ค. ๊ฐ๋ฐ์์ ์์ฐ์ฑ์ด ๋ฐ๋ฅ์ ์น๋ ์๊ฐ์ด์ง.
2. ๋งคํฌ๋ก ์ค์ผ ๐ฆ
ํค๋ ํ์ผ์ #define ๋งคํฌ๋ก๊ฐ ์๋์น ์๊ฒ ๋ค๋ฅธ ์ฝ๋์ ์ํฅ์ ์ค ์ ์์ด. ํนํ ์ผ๋ฐ์ ์ธ ์ด๋ฆ์ ์ฌ์ฉํ๋ฉด ์ถฉ๋ ๊ฐ๋ฅ์ฑ์ด ๋์์ ธ.
3. ์ํ ์์กด์ฑ ์ง์ฅ ๐
A.h๊ฐ B.h๋ฅผ includeํ๊ณ , B.h๊ฐ ๋ค์ A.h๋ฅผ includeํ๋ฉด? ์ปดํ์ผ๋ฌ๊ฐ ๋ฉ๋ถ์ ๋น ์ง์ง. ์ ๋ฐฉ ์ ์ธ(forward declaration)์ผ๋ก ํด๊ฒฐํ๋ ค๋ค ์ฝ๋๊ฐ ๋ ๋ณต์กํด์ง๊ณ ...
4. ์บก์ํ ๋ถ์กฑ ๐
ํค๋ ํ์ผ์ ์ ์ธ๋ ๋ชจ๋ ๊ฒ ๋
ธ์ถ๋ผ. private ๊ตฌํ ์ธ๋ถ์ฌํญ๊น์ง ํค๋์ ๋ค์ด๊ฐ์ผ ํ๋ ์ ๋ณด ์๋์ด ์ ๋๋ก ์ ๋ผ.
๐ ๋ชจ๋์ ํต์ฌ ๊ฐ๋ ๊ณผ ์๋ ์๋ฆฌ
๋ชจ๋์ ์ด๋ฐ ๋ฌธ์ ๋ค์ ๊ทผ๋ณธ์ ์ผ๋ก ํด๊ฒฐํด. ์ด๋ป๊ฒ? ์ปดํ์ผ๋ ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ด์ผ!
๋ชจ๋์ ์ปดํ์ผํ๋ฉด BMI(Binary Module Interface)๋ผ๋ ์ค๊ฐ ํ์ผ์ด ์์ฑ๋ผ. ์ด๊ฑด ์ด๋ฏธ ํ์ฑ๋๊ณ ์ฒ๋ฆฌ๋ ๋ฐ์ด๋๋ฆฌ ํํ์ ์ธํฐํ์ด์ค ์ ๋ณด์ผ. ๋ค๋ฅธ ํ์ผ์์ ์ด ๋ชจ๋์ importํ๋ฉด ํ
์คํธ๋ฅผ ๋ค์ ํ์ฑํ ํ์ ์์ด BMI๋ฅผ ๋ฐ๋ก ์ฝ์ด๋ค์ฌ. ๐
๐ฆ ๋ชจ๋์ 3๊ฐ์ง ํต์ฌ ์์
ํ์ผ์ ๋งจ ์์์ "์ด ํ์ผ์ ๋ชจ๋์ด์ผ!"๋ผ๊ณ ์ ์ธํ๋ ๋ถ๋ถ์ด์ผ.
export module MyModule; // ์ด ํ์ผ์ MyModule์ด๋ผ๋ ๋ชจ๋์
๋๋ค!
์ธ๋ถ์์ ์ฌ์ฉํ ์ ์๋๋ก ๊ณต๊ฐํ๋ ๋ถ๋ถ. export ํค์๋๋ฅผ ๋ถ์ธ ๊ฒ๋ง ์ธ๋ถ์์ ์ ๊ทผ ๊ฐ๋ฅํด.
export module MyModule;
export int add(int a, int b) { // ์ธ๋ถ์์ ์ฌ์ฉ ๊ฐ๋ฅ
return a + b;
}
int multiply(int a, int b) { // ๋ชจ๋ ๋ด๋ถ์์๋ง ์ฌ์ฉ ๊ฐ๋ฅ
return a * b;
}
๋ค๋ฅธ ๋ชจ๋์ ์ฌ์ฉํ๋ ค๋ฉด import ํค์๋๋ฅผ ์จ. #include์ ๋น์ทํ์ง๋ง ํจ์ฌ ๋๋ํด!
import MyModule; // MyModule์ ๊ณต๊ฐ๋ ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ ธ์ด
int main() {
int result = add(3, 5); // MyModule์ add ํจ์ ์ฌ์ฉ
return 0;
}
๐๏ธ ๋๊ท๋ชจ ํ๋ก์ ํธ์์ ๋ชจ๋ ๊ตฌ์กฐํ ์ ๋ต
์, ์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก ๋๊ท๋ชจ ํ๋ก์ ํธ์์ ๋ชจ๋์ ์ด๋ป๊ฒ ๊ตฌ์กฐํํ ์ง ์์๋ณด์. ์์ญ๋ง ์ค์ ์ฝ๋๋ฅผ ๊ด๋ฆฌํ๋ ์ค์ ์ ๋ต์ด์ผ! ๐ช
๐จ 1๋จ๊ณ: ๋ ผ๋ฆฌ์ ๊ณ์ธต ๊ตฌ์กฐ ์ค๊ณ
ํ๋ก์ ํธ๋ฅผ ๋ ผ๋ฆฌ์ ์ธ ๊ณ์ธต์ผ๋ก ๋๋๋ ๊ฒ ์ฒซ ๋ฒ์งธ์ผ. ์ผ๋ฐ์ ์ผ๋ก ์ด๋ฐ ๊ตฌ์กฐ๋ฅผ ๋ง์ด ์จ:
โข Core Layer (ํต์ฌ ๊ณ์ธต)
๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ์ ํธ๋ฆฌํฐ์ ๋ฐ์ดํฐ ๊ตฌ์กฐ. ๋ค๋ฅธ ๋ชจ๋ ๊ณ์ธต์ด ์์กดํ๋ ๊ธฐ๋ฐ.
โข Domain Layer (๋๋ฉ์ธ ๊ณ์ธต)
๋น์ฆ๋์ค ๋ก์ง๊ณผ ๋๋ฉ์ธ ๋ชจ๋ธ. ์ ํ๋ฆฌ์ผ์ด์
์ ํต์ฌ ๊ธฐ๋ฅ.
โข Service Layer (์๋น์ค ๊ณ์ธต)
์ธ๋ถ ์์คํ
๊ณผ์ ํต์ , ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ๊ทผ ๋ฑ.
โข Presentation Layer (ํํ ๊ณ์ธต)
UI, API ์๋ํฌ์ธํธ ๋ฑ ์ฌ์ฉ์ ์ธํฐํ์ด์ค.
๐ ์ค์ ํ๋ก์ ํธ ๊ตฌ์กฐ ์์
๋ํ ๊ฒ์ ์์ง์ ์๋ก ๋ค์ด๋ณผ๊ฒ. ์ด๋ฐ ์์ผ๋ก ๋ชจ๋์ ๊ตฌ์ฑํ ์ ์์ด:
GameEngine/
โโโ Core/
โ โโโ Math.cppm // export module GameEngine.Core.Math;
โ โโโ Memory.cppm // export module GameEngine.Core.Memory;
โ โโโ Threading.cppm // export module GameEngine.Core.Threading;
โ โโโ Core.cppm // export module GameEngine.Core; (ํตํฉ ๋ชจ๋)
โ
โโโ Graphics/
โ โโโ Renderer.cppm // export module GameEngine.Graphics.Renderer;
โ โโโ Shader.cppm // export module GameEngine.Graphics.Shader;
โ โโโ Texture.cppm // export module GameEngine.Graphics.Texture;
โ โโโ Graphics.cppm // export module GameEngine.Graphics;
โ
โโโ Physics/
โ โโโ RigidBody.cppm // export module GameEngine.Physics.RigidBody;
โ โโโ Collision.cppm // export module GameEngine.Physics.Collision;
โ โโโ Physics.cppm // export module GameEngine.Physics;
โ
โโโ Audio/
โ โโโ SoundEngine.cppm // export module GameEngine.Audio.SoundEngine;
โ โโโ Music.cppm // export module GameEngine.Audio.Music;
โ โโโ Audio.cppm // export module GameEngine.Audio;
โ
โโโ GameEngine.cppm // export module GameEngine; (์ต์์ ํตํฉ)
์ด๋ ๊ฒ ๊ณ์ธต์ ์ผ๋ก ๊ตฌ์ฑํ๋ฉด ์์กด์ฑ์ด ๋ช ํํด์ง๊ณ , ํ์ํ ๋ถ๋ถ๋ง ์ ํ์ ์ผ๋ก importํ ์ ์์ด! ๐ฏ
๐ 2๋จ๊ณ: ๋ชจ๋ ํํฐ์ ํ์ฉํ๊ธฐ
ํฐ ๋ชจ๋์ ์ฌ๋ฌ ํํฐ์ ์ผ๋ก ๋๋ ์ ์์ด. ์ด๊ฑด ๋ชจ๋ ๋ด๋ถ๋ฅผ ๋ ์ธ๋ฐํ๊ฒ ์กฐ์งํํ๋ ๋ฐฉ๋ฒ์ด์ผ.
// Math.cppm - ๋ฉ์ธ ๋ชจ๋ ์ธํฐํ์ด์ค
export module GameEngine.Core.Math;
export import :Vector; // ํํฐ์
import
export import :Matrix;
export import :Quaternion;
// Vector.cppm - ๋ชจ๋ ํํฐ์
export module GameEngine.Core.Math:Vector;
export class Vector3 {
public:
float x, y, z;
Vector3(float x = 0, float y = 0, float z = 0)
: x(x), y(y), z(z) {}
Vector3 operator+(const Vector3& other) const {
return Vector3(x + other.x, y + other.y, z + other.z);
}
float length() const;
Vector3 normalize() const;
};
// Matrix.cppm - ๋ ๋ค๋ฅธ ํํฐ์
export module GameEngine.Core.Math:Matrix;
import :Vector; // ๊ฐ์ ๋ชจ๋์ ๋ค๋ฅธ ํํฐ์
import ๊ฐ๋ฅ!
export class Matrix4x4 {
float data[16];
public:
Matrix4x4();
Vector3 transform(const Vector3& v) const;
Matrix4x4 operator*(const Matrix4x4& other) const;
};
ํํฐ์
์ ์ฐ๋ฉด ํฐ ๋ชจ๋์ ๋
ผ๋ฆฌ์ ์ผ๋ก ๋ถํ ํ๋ฉด์๋ ํ๋์ ๋ชจ๋๋ก ๊ด๋ฆฌํ ์ ์์ด. ์ธ๋ถ์์๋ ๊ทธ๋ฅ import GameEngine.Core.Math; ํ๋๋ฉด ๋! ๐
module MyModule:Partition ์ด๋ฐ ์์ผ๋ก! ์ด๋ ๊ฒ ํ๋ฉด ํํฐ์
์ด ๋ชจ๋์ ์ผ๋ถ๋ผ๋ ๊ฑธ ๋ช
ํํ ํํํ ์ ์์ด.
๐ญ 3๋จ๊ณ: ์ธํฐํ์ด์ค์ ๊ตฌํ ๋ถ๋ฆฌ
๋ชจ๋์์๋ ์ธํฐํ์ด์ค์ ๊ตฌํ์ ๋ถ๋ฆฌํ ์ ์์ด. ์ด๊ฑด ์ปดํ์ผ ์๊ฐ์ ๋์ฑ ์ค์ด๋ ๊ฐ๋ ฅํ ๊ธฐ๋ฒ์ด์ผ!
๋ชจ๋ ์ธํฐํ์ด์ค ์ ๋ (Module Interface Unit)
// Database.cppm
export module GameEngine.Database;
import std; // ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ชจ๋
export class DatabaseConnection {
public:
DatabaseConnection(std::string_view connectionString);
~DatabaseConnection();
bool connect();
void disconnect();
std::vector<std::string> executeQuery(std::string_view query);
bool executeCommand(std::string_view command);
private:
struct Impl; // Pimpl ํจํด
std::unique_ptr<Impl> pImpl;
};
๋ชจ๋ ๊ตฌํ ์ ๋ (Module Implementation Unit)
// Database_impl.cpp
module GameEngine.Database; // export ์์! ๊ตฌํ ์ ๋
import ThirdParty.SQLite; // ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
struct DatabaseConnection::Impl {
sqlite3* db;
std::string connectionString;
bool isConnected;
Impl(std::string_view connStr)
: db(nullptr), connectionString(connStr), isConnected(false) {}
};
DatabaseConnection::DatabaseConnection(std::string_view connectionString)
: pImpl(std::make_unique<Impl>(connectionString)) {}
DatabaseConnection::~DatabaseConnection() {
if (pImpl->isConnected) {
disconnect();
}
}
bool DatabaseConnection::connect() {
int result = sqlite3_open(pImpl->connectionString.c_str(), &pImpl->db);
pImpl->isConnected = (result == SQLITE_OK);
return pImpl->isConnected;
}
// ... ๋๋จธ์ง ๊ตฌํ
์ด๋ ๊ฒ ํ๋ฉด ๊ตฌํ ์ธ๋ถ์ฌํญ์ด ์์ ํ ์จ๊ฒจ์ ธ. SQLite ๊ฐ์ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์กด์ฑ๋ ๋ชจ๋ ์ธํฐํ์ด์ค์ ๋ ธ์ถ๋์ง ์์! ๐
export ํค์๋๋ฅผ ๋นผ์ผ ํด. module ModuleName;๋ง ์ฐ๋ฉด ๋ผ. ์ด๊ฒ ์ธํฐํ์ด์ค ์ ๋๊ณผ ๊ตฌํ ์ ๋์ ๊ตฌ๋ถํ๋ ๋ฐฉ๋ฒ์ด์ผ!
โก ์ปดํ์ผ ์๊ฐ ์ต์ ํ ์ค์ ํ ํฌ๋
๋ชจ๋์ ๊ฐ์ฅ ํฐ ์ฅ์ ์ค ํ๋๊ฐ ๋ฐ๋ก ์ปดํ์ผ ์๋ ํฅ์์ด์ผ. ํ์ง๋ง ์ ๋๋ก ํ์ฉํ์ง ์์ผ๋ฉด ๊ทธ ์ด์ ์ ๋ชป ๋๋ฆด ์๋ ์์ด. ์ค์ ์ต์ ํ ๊ธฐ๋ฒ๋ค์ ์์๋ณด์! โก
๐ ์ต์ ํ ์ ๋ต 1: ์ ๋ฐฉ ์ ์ธ ๋์ ๋ชจ๋ ํํฐ์
์ ํต์ ์ธ ๋ฐฉ์์์๋ ์ปดํ์ผ ์๊ฐ์ ์ค์ด๋ ค๊ณ ์ ๋ฐฉ ์ ์ธ์ ๋ง์ด ์ผ์ด. ํ์ง๋ง ๋ชจ๋์์๋ ํํฐ์ ์ด ๋ ๋์ ์ ํ์ด์ผ!
// ๋์ ์: ์ ๋ฐฉ ์ ์ธ ๋จ๋ฐ
export module GameEngine.Graphics;
class Texture; // ์ ๋ฐฉ ์ ์ธ
class Shader; // ์ ๋ฐฉ ์ ์ธ
class Material; // ์ ๋ฐฉ ์ ์ธ
export class Renderer {
void setTexture(Texture* tex);
void setShader(Shader* shader);
// ...
};
// ์ข์ ์: ํํฐ์
ํ์ฉ
export module GameEngine.Graphics;
export import :Texture; // ํํฐ์
์ผ๋ก ๋ถ๋ฆฌ
export import :Shader;
export import :Material;
export class Renderer {
void setTexture(const Texture& tex);
void setShader(const Shader& shader);
// ...
};
ํํฐ์ ์ ์ฐ๋ฉด ํ์ ์ ๋ณด๊ฐ ์์ ํ ์ ๋ฌ๋๋ฉด์๋ ์ปดํ์ผ ์๊ฐ์ด ์ต์ํ๋ผ. ํฌ์ธํฐ๋ ์ฐธ์กฐ๋ง ์ฐ๋ ๊ฒ ์๋๋ผ ๊ฐ์ผ๋ก๋ ์ ๋ฌํ ์ ์์ด์ ๋ ์์ ํ๊ณ ! ๐ก๏ธ
๐ฏ ์ต์ ํ ์ ๋ต 2: ํค๋ ์ ๋ ํ์ฉ
๊ธฐ์กด ํค๋ ํ์ผ์ ๋ชจ๋์ฒ๋ผ importํ ์ ์๋ ๊ธฐ๋ฅ์ด ์์ด. ์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ธ ๋ ์ ์ฉํด!
// ์ ํต์ ์ธ ๋ฐฉ์
#include <vector>
#include <string>
#include <memory>
// ๋ชจ๋ ๋ฐฉ์ (C++23๋ถํฐ ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ชจ๋ ์ง์)
import std; // ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ์ฒด๋ฅผ ๋ชจ๋๋ก!
// ๋๋ ํน์ ํค๋๋ง
import <vector>;
import <string>;
import <memory>;
import std; ํ๋๋ก ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ์ฒด๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ด. ์์ญ ๊ฐ์ #include๋ฅผ ๋์ฒดํ๋ฉด์๋ ์ปดํ์ผ ์๊ฐ์ ํจ์ฌ ๋นจ๋ผ์ ธ! ๐โโ๏ธ
๐ ์ค์ ์ฑ๋ฅ ๋น๊ต
์ค์ ํ๋ก์ ํธ์์ ์ธก์ ํ ์ปดํ์ผ ์๊ฐ ๋น๊ต์ผ. (10๋ง ์ค ๊ท๋ชจ์ ํ๋ก์ ํธ ๊ธฐ์ค)
| ๋ฐฉ์ | ์ด๊ธฐ ๋น๋ | ์ฆ๋ถ ๋น๋ (1๊ฐ ํ์ผ ์์ ) | ํด๋ฆฐ ๋น๋ |
|---|---|---|---|
| ์ ํต์ ํค๋ | 8๋ถ 30์ด | 2๋ถ 15์ด | 8๋ถ 45์ด |
| ํ๋ฆฌ์ปดํ์ผ ํค๋ | 6๋ถ 20์ด | 1๋ถ 40์ด | 6๋ถ 30์ด |
| C++20 ๋ชจ๋ | 3๋ถ 10์ด | 25์ด | 3๋ถ 15์ด |
๋ณด๋ค์ํผ ๋ชจ๋์ ์ฐ๋ฉด ์ปดํ์ผ ์๊ฐ์ด ์ ๋ฐ ์ด์ ์ค์ด๋ค์ด! ํนํ ์ฆ๋ถ ๋น๋์์ ์ฐจ์ด๊ฐ ๊ทน๋ช ํ์ง. ํ๋ฃจ์ ์์ญ ๋ฒ ๋น๋ํ๋ ๊ฑธ ์๊ฐํ๋ฉด ์์ฒญ๋ ์๊ฐ ์ ์ฝ์ด์ผ! โฐ
๐ง ๋น๋ ์์คํ ์ค์ ํ๊ธฐ
๋ชจ๋์ ์ค์ ๋ก ์ฌ์ฉํ๋ ค๋ฉด ๋น๋ ์์คํ ์ค์ ์ด ํ์ํด. ์ฃผ์ ๋น๋ ๋๊ตฌ๋ค์์ ์ด๋ป๊ฒ ์ค์ ํ๋์ง ์์๋ณด์! ๐ ๏ธ
๐ฆ CMake ์ค์
CMake 3.28๋ถํฐ C++20 ๋ชจ๋์ ์คํ์ ์ผ๋ก ์ง์ํด. ์์ง ์๋ฒฝํ์ง ์์ง๋ง ๊ณ์ ๊ฐ์ ๋๊ณ ์์ด!
cmake_minimum_required(VERSION 3.28)
project(MyProject CXX)
# C++20 ํ์ฑํ
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# ์คํ์ ๋ชจ๋ ์ง์ ํ์ฑํ
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "2182bf5c-ef0d-489a-91da-49dbc3090d2a")
set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP ON)
# ๋ชจ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ์
add_library(GameEngineCore)
target_sources(GameEngineCore
PUBLIC
FILE_SET CXX_MODULES FILES
Core/Math.cppm
Core/Memory.cppm
Core/Threading.cppm
Core/Core.cppm
)
# ๋ชจ๋์ ์ฌ์ฉํ๋ ์คํ ํ์ผ
add_executable(Game main.cpp)
target_link_libraries(Game PRIVATE GameEngineCore)
FILE_SET CXX_MODULES๊ฐ ํต์ฌ์ด์ผ. ์ด๊ฑธ๋ก CMake์๊ฒ "์ด ํ์ผ๋ค์ ๋ชจ๋์ด์ผ!"๋ผ๊ณ ์๋ ค์ฃผ๋ ๊ฑฐ์ง.
๐จ Visual Studio ์ค์
Visual Studio 2019 16.10 ์ด์์์ C++20 ๋ชจ๋์ ์ง์ํด. ํ๋ก์ ํธ ์ค์ ์์ ๋ช ๊ฐ์ง๋ง ๋ฐ๊ฟ์ฃผ๋ฉด ๋ผ!
1. ํ๋ก์ ํธ ์์ฑ ์ด๊ธฐ
ํ๋ก์ ํธ ์ฐํด๋ฆญ โ ์์ฑ
2. C/C++ โ ์ธ์ด ์ค์
โข C++ ์ธ์ด ํ์ค: ISO C++20 ํ์ค(/std:c++20)
โข C++ ๋ชจ๋ ์ฌ์ฉ: ์(/interface /internalPartition)
3. ๋ชจ๋ ํ์ผ ์ถ๊ฐ
.cppm ๋๋ .ixx ํ์ฅ์๋ก ๋ชจ๋ ํ์ผ ์์ฑ
ํ์ผ ์์ฑ์์ "ํญ๋ชฉ ํ์"์ "C/C++ ์ปดํ์ผ๋ฌ"๋ก ์ค์
4. ๋น๋ ์์ ์ค์
๋ชจ๋ ๊ฐ ์์กด์ฑ์ ๋ฐ๋ผ ๋น๋ ์์๊ฐ ์๋์ผ๋ก ๊ฒฐ์ ๋ผ. ํ์ง๋ง ๋ณต์กํ ๊ฒฝ์ฐ ์๋์ผ๋ก ์กฐ์ ์ด ํ์ํ ์๋ ์์ด.
๐ฆ Clang/LLVM ์ค์
Clang 15 ์ด์์์ C++20 ๋ชจ๋์ ์ง์ํด. ๋ช ๋ น์ค์์ ์ด๋ ๊ฒ ์ปดํ์ผํ ์ ์์ด:
# ๋ชจ๋ ์ธํฐํ์ด์ค ์ปดํ์ผ (BMI ์์ฑ)
clang++ -std=c++20 -c Math.cppm -Xclang -emit-module-interface -o Math.pcm
# ๋ชจ๋์ ์ฌ์ฉํ๋ ํ์ผ ์ปดํ์ผ
clang++ -std=c++20 -c main.cpp -fmodule-file=Math.pcm -o main.o
# ๋งํฌ
clang++ main.o Math.o -o program
-Xclang -emit-module-interface๊ฐ BMI๋ฅผ ์์ฑํ๋ ์ต์
์ด์ผ. -fmodule-file๋ก ์์ฑ๋ BMI๋ฅผ ์ง์ ํด์ฃผ๋ฉด ๋ผ!
๐จ ๋ชจ๋ ์ค๊ณ ๋ฒ ์คํธ ํ๋ํฐ์ค
์ด์ ์ค์ ์์ ๋ฐ๋ก ์ธ ์ ์๋ ๋ชจ๋ ์ค๊ณ ์์น๋ค์ ์์๋ณด์. ์ด๊ฑด ์๋ง์ ์ํ์ฐฉ์ค๋ฅผ ๊ฑฐ์ณ ์ ๋ฆฝ๋ ๋ ธํ์ฐ๋ค์ด์ผ! ๐
โ ์์น 1: ๋จ์ผ ์ฑ ์ ์์น (Single Responsibility)
ํ๋์ ๋ชจ๋์ ํ๋์ ๋ช ํํ ์ฑ ์๋ง ๊ฐ์ ธ์ผ ํด. ๋๋ฌด ๋ง์ ๊ธฐ๋ฅ์ ํ ๋ชจ๋์ ๋๋ ค๋ฃ์ง ๋ง!
// โ ๋์ ์: ๋๋ฌด ๋ง์ ์ฑ
์
export module Utils; // ์ด๋ฆ๋ถํฐ ์ ๋งคํจ
export class FileIO { /* ... */ };
export class NetworkSocket { /* ... */ };
export class JsonParser { /* ... */ };
export class Logger { /* ... */ };
export class Random { /* ... */ };
// โ
์ข์ ์: ๋ช
ํํ ์ฑ
์ ๋ถ๋ฆฌ
export module FileSystem;
export class FileReader { /* ... */ };
export class FileWriter { /* ... */ };
export module Network;
export class TcpSocket { /* ... */ };
export class HttpClient { /* ... */ };
export module Serialization;
export class JsonParser { /* ... */ };
export class XmlParser { /* ... */ };
๊ฐ ๋ชจ๋์ด ๋ช ํํ ๋ชฉ์ ์ ๊ฐ์ง๋ฉด ์ดํดํ๊ธฐ ์ฝ๊ณ , ์ฌ์ฌ์ฉํ๊ธฐ๋ ์ข์! ๐ฏ
โ ์์น 2: ์ต์ ์ธํฐํ์ด์ค ๋ ธ์ถ
๊ผญ ํ์ํ ๊ฒ๋ง exportํด. ๋ด๋ถ ๊ตฌํ ์ธ๋ถ์ฌํญ์ ์จ๊ฒจ์ผ ํด!
export module Database;
import std;
// ๋ด๋ถ ํฌํผ ํจ์ (export ์์ = ์ธ๋ถ์์ ์ ๊ทผ ๋ถ๊ฐ)
namespace internal {
std::string sanitizeQuery(std::string_view query) {
// SQL ์ธ์ ์
๋ฐฉ์ง ๋ก์ง
// ...
}
bool validateConnection(void* handle) {
// ์ฐ๊ฒฐ ์ ํจ์ฑ ๊ฒ์ฌ
// ...
}
}
// ๊ณต๊ฐ ์ธํฐํ์ด์ค๋ง export
export class Database {
public:
bool connect(std::string_view connectionString);
std::vector<Row> query(std::string_view sql);
private:
void* handle; // ๋ด๋ถ ๊ตฌํ ์ธ๋ถ์ฌํญ
};
์ด๋ ๊ฒ ํ๋ฉด ๋์ค์ ๋ด๋ถ ๊ตฌํ์ ๋ฐ๊ฟ๋ ์ธ๋ถ ์ฝ๋์ ์ํฅ์ ์ฃผ์ง ์์. ์บก์ํ์ ์ง์์ง! ๐
โ ์์น 3: ์์กด์ฑ ์ต์ํ
๋ชจ๋์ด ๋ค๋ฅธ ๋ชจ๋์ ์์กดํ๋ ๊ฑธ ์ต์ํํด. ์์กด์ฑ์ด ๋ง์์๋ก ๊ฒฐํฉ๋๊ฐ ๋์์ง๊ณ ์ ์ง๋ณด์๊ฐ ์ด๋ ค์์ ธ.
// โ ๋์ ์: ๊ณผ๋ํ ์์กด์ฑ
export module UserInterface;
import Graphics;
import Audio;
import Network;
import Database;
import Physics;
import AI; // UI๊ฐ ์ AI๋ฅผ ์์กดํด?
// โ
์ข์ ์: ํ์ํ ๊ฒ๋ง ์์กด
export module UserInterface;
import Graphics; // UI ๋ ๋๋ง์ ํ์
import Input; // ์ฌ์ฉ์ ์
๋ ฅ ์ฒ๋ฆฌ์ ํ์
// ๋ค๋ฅธ ๊ธฐ๋ฅ์ ์ธํฐํ์ด์ค๋ฅผ ํตํด ์ฃผ์
๋ฐ์
export class UIManager {
public:
void setEventHandler(IEventHandler* handler);
void setDataProvider(IDataProvider* provider);
// ...
};
์์กด์ฑ ์ฃผ์ (Dependency Injection) ํจํด์ ํ์ฉํ๋ฉด ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ ์ ์์ด! ๐
โ ์์น 4: ์ํ ์์กด์ฑ ์ ๋ ๊ธ์ง
A ๋ชจ๋์ด B๋ฅผ importํ๊ณ , B๊ฐ ๋ค์ A๋ฅผ importํ๋ ์ํ ์์กด์ฑ์ ์ ๋ ๋ง๋ค๋ฉด ์ ๋ผ!
// โ ์ ๋ ์ด๋ฌ์ง ๋ง!
// ModuleA.cppm
export module A;
import B; // B๋ฅผ ์์กด
export class ClassA {
ClassB* b; // B์ ํ์
์ฌ์ฉ
};
// ModuleB.cppm
export module B;
import A; // A๋ฅผ ์์กด โ ์ํ!
export class ClassB {
ClassA* a; // A์ ํ์
์ฌ์ฉ
};
// โ
ํด๊ฒฐ ๋ฐฉ๋ฒ 1: ๊ณตํต ์ธํฐํ์ด์ค ๋ถ๋ฆฌ
// Interface.cppm
export module Interface;
export class IComponentA { /* ... */ };
export class IComponentB { /* ... */ };
// ModuleA.cppm
export module A;
import Interface;
export class ClassA : public IComponentA {
IComponentB* b; // ์ธํฐํ์ด์ค๋ง ์์กด
};
// ModuleB.cppm
export module B;
import Interface;
export class ClassB : public IComponentB {
IComponentA* a; // ์ธํฐํ์ด์ค๋ง ์์กด
};
์ํ ์์กด์ฑ์ด ์๊ธฐ๋ฉด ์ปดํ์ผ ์์๋ฅผ ๊ฒฐ์ ํ ์ ์์ด์ ๋น๋๊ฐ ์คํจํด. ์ค๊ณ ๋จ๊ณ์์ ๋ฏธ๋ฆฌ ๋ฐฉ์งํ๋ ๊ฒ ์ค์ํด! ๐ซ
๐ ๊ธฐ์กด ํ๋ก์ ํธ๋ฅผ ๋ชจ๋๋ก ๋ง์ด๊ทธ๋ ์ด์ ํ๊ธฐ
์ ํ๋ก์ ํธ๋ ์ฒ์๋ถํฐ ๋ชจ๋๋ก ์์ํ๋ฉด ๋์ง๋ง, ๊ธฐ์กด ๋๊ท๋ชจ ํ๋ก์ ํธ๋ ์ด๋ป๊ฒ ํ ๊น? ๋จ๊ณ์ ๋ง์ด๊ทธ๋ ์ด์ ์ ๋ต์ ์์๋ณด์! ๐
๐ 1๋จ๊ณ: ํํฉ ๋ถ์ ๋ฐ ๊ณํ ์๋ฆฝ
๋จผ์ ํ๋ก์ ํธ์ ํ์ฌ ์ํ๋ฅผ ํ์ ํด์ผ ํด.
๋ถ์ํ ํญ๋ชฉ๋ค:
โข ์ ์ฒด ํ์ผ ์์ ์ฝ๋ ๋ผ์ธ ์
โข ํค๋ ํ์ผ ์์กด์ฑ ๊ทธ๋ํ
โข ์ปดํ์ผ ์๊ฐ ๋ณ๋ชฉ ์ง์
โข ์ํ ์์กด์ฑ ์กด์ฌ ์ฌ๋ถ
โข ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์กด์ฑ
๋๊ตฌ๋ฅผ ํ์ฉํ๋ฉด ์ข์. include-what-you-use, cpp-dependencies ๊ฐ์ ๋๊ตฌ๋ก ์์กด์ฑ์ ์๊ฐํํ ์ ์์ด! ๐
๐ฏ 2๋จ๊ณ: ์ฐ์ ์์ ๊ฒฐ์
๋ชจ๋ ๊ฑธ ํ ๋ฒ์ ๋ฐ๊พธ๋ ค๊ณ ํ๋ฉด ๋งํด. ์ฐ์ ์์๋ฅผ ์ ํด์ ๋จ๊ณ์ ์ผ๋ก ์งํํด์ผ ํด!
1์์: ๋ ๋ฆฝ์ ์ธ ์ ํธ๋ฆฌํฐ ๋ชจ๋
๋ค๋ฅธ ์ฝ๋์ ์์กดํ์ง ์๋ ๊ธฐ๋ณธ ์ ํธ๋ฆฌํฐ๋ถํฐ ์์. ์: ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ, ๋ฌธ์์ด ์ฒ๋ฆฌ, ๋ก๊น
2์์: ํ์ ๊ณ์ธต ๋ชจ๋
Core ๊ณ์ธต์ฒ๋ผ ๋ค๋ฅธ ๋ชจ๋์ ๊ธฐ๋ฐ์ด ๋๋ ๋ถ๋ถ
3์์: ์ค๊ฐ ๊ณ์ธต ๋ชจ๋
Domain, Service ๊ณ์ธต
4์์: ์์ ๊ณ์ธต ๋ชจ๋
UI, API ๊ฐ์ ์ต์์ ๊ณ์ธต
์ด๋ ๊ฒ ํ๋ฉด ์์กด์ฑ ๋ฐฉํฅ์ ๋ฐ๋ผ ์์ฐ์ค๋ฝ๊ฒ ๋ง์ด๊ทธ๋ ์ด์ ํ ์ ์์ด! ๐
๐ง 3๋จ๊ณ: ํ์ด๋ธ๋ฆฌ๋ ์ ๊ทผ๋ฒ
๋ชจ๋๊ณผ ํค๋๋ฅผ ๋์์ ์ง์ํ๋ ๊ณผ๋๊ธฐ ์ ๋ต์ด์ผ. ์ ์ง์ ์ ํ์ ํ์์ ์ด์ง!
// Math.cppm - ๋ชจ๋ ์ธํฐํ์ด์ค
export module Math;
export namespace math {
double sqrt(double x);
double pow(double base, double exp);
}
// Math.h - ํธํ์ฑ์ ์ํ ํค๋ (์ ํ์ )
#ifndef MATH_H
#define MATH_H
// ๋ชจ๋์ ์ง์ํ๋ ์ปดํ์ผ๋ฌ๋ฉด import
#if __cpp_modules >= 201907L
import Math;
#else
// ์๋๋ฉด ์ ํต์ ์ธ ์ ์ธ
namespace math {
double sqrt(double x);
double pow(double base, double exp);
}
#endif
#endif // MATH_H
์ด๋ ๊ฒ ํ๋ฉด ๋ชจ๋์ ์ง์ํ์ง ์๋ ์ปดํ์ผ๋ฌ๋ ์์ง ๋ง์ด๊ทธ๋ ์ด์ ํ์ง ์์ ์ฝ๋์์๋ ์ฌ์ฉํ ์ ์์ด! ๐
โ 4๋จ๊ณ: ํ ์คํธ์ ๊ฒ์ฆ
๊ฐ ๋จ๊ณ๋ง๋ค ์ฒ ์ ํ ํ ์คํธ๊ฐ ํ์์ผ!
๊ฒ์ฆ ์ฒดํฌ๋ฆฌ์คํธ:
โ ๋ชจ๋ ๋จ์ ํ
์คํธ ํต๊ณผ
โ ํตํฉ ํ
์คํธ ํต๊ณผ
โ ์ปดํ์ผ ์๊ฐ ์ธก์ ๋ฐ ๋น๊ต
โ ์คํ ํ์ผ ํฌ๊ธฐ ํ์ธ
โ ๋ฐํ์ ์ฑ๋ฅ ๋ฒค์น๋งํฌ
โ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ํ๋กํ์ผ๋ง
ํนํ ์ปดํ์ผ ์๊ฐ์ด ์ค์ ๋ก ๊ฐ์ ๋๋์ง ํ์ธํ๋ ๊ฒ ์ค์ํด. ์๋ชป ์ค๊ณํ๋ฉด ์คํ๋ ค ๋๋ ค์ง ์๋ ์๊ฑฐ๋ ! โฑ๏ธ
๐ ํํ ๋ฌธ์ ๋ค๊ณผ ํด๊ฒฐ ๋ฐฉ๋ฒ
๋ชจ๋์ ์ฒ์ ์ฐ๋ค ๋ณด๋ฉด ์ฌ๋ฌ ๋ฌธ์ ์ ๋ถ๋ชํ๊ฒ ๋ผ. ์์ฃผ ๊ฒช๋ ๋ฌธ์ ๋ค๊ณผ ํด๊ฒฐ์ฑ ์ ์ ๋ฆฌํด๋ดค์ด! ๐
โ ๋ฌธ์ 1: "๋ชจ๋์ ์ฐพ์ ์ ์์ต๋๋ค" ์๋ฌ
// main.cpp
import MyModule; // ์๋ฌ: ๋ชจ๋์ ์ฐพ์ ์ ์์
int main() {
// ...
}
์์ธ:
โข ๋ชจ๋์ด ์์ง ์ปดํ์ผ๋์ง ์์๊ฑฐ๋
โข BMI ํ์ผ ๊ฒฝ๋ก๊ฐ ์๋ชป ์ค์ ๋๊ฑฐ๋
โข ๋น๋ ์์๊ฐ ์๋ชป๋์ ๋
ํด๊ฒฐ ๋ฐฉ๋ฒ:
1. ๋ชจ๋ ํ์ผ์ด ๋จผ์ ์ปดํ์ผ๋๋๋ก ๋น๋ ์์ ์กฐ์
2. ์ปดํ์ผ๋ฌ์ BMI ๊ฒฝ๋ก ๋ช
์์ ์ผ๋ก ์ง์
3. ๋น๋ ์์คํ
(CMake ๋ฑ) ์ค์ ํ์ธ
// CMake์์ ์์กด์ฑ ๋ช
์
add_executable(MyApp main.cpp)
target_link_libraries(MyApp PRIVATE MyModuleLib) # ๋ชจ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋งํฌ
โ ๋ฌธ์ 2: ํ ํ๋ฆฟ ์ ์๊ฐ ๋ณด์ด์ง ์์
// Container.cppm
export module Container;
export template<typename T>
class Vector {
public:
void push_back(const T& value);
// ...
};
// ๊ตฌํ์ ๋ณ๋ ํ์ผ์ ๋๋ฉด ์ ๋ผ!
// Vector.cpp
module Container;
template<typename T>
void Vector<T>::push_back(const T& value) {
// ์ด ์ ์๊ฐ ์ธ๋ถ์์ ๋ณด์ด์ง ์์!
}
์์ธ:
ํ
ํ๋ฆฟ์ ์ธ์คํด์คํ ์์ ์ ์ ์๊ฐ ํ์ํ๋ฐ, ๋ชจ๋ ๊ตฌํ ์ ๋์ ์์ผ๋ฉด ์ ๊ทผํ ์ ์์ด.
ํด๊ฒฐ ๋ฐฉ๋ฒ:
ํ
ํ๋ฆฟ ์ ์๋ฅผ ๋ชจ๋ ์ธํฐํ์ด์ค ์ ๋์ ํฌํจ์์ผ์ผ ํด!
// Container.cppm - ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ
export module Container;
export template<typename T>
class Vector {
public:
void push_back(const T& value) {
// ์ ์๋ฅผ ์ฌ๊ธฐ์!
data.push_back(value);
}
private:
std::vector<T> data;
};
โ ๋ฌธ์ 3: ๋งคํฌ๋ก๊ฐ ์๋ํ์ง ์์
// Config.h
#define MAX_BUFFER_SIZE 1024
#define DEBUG_MODE
// MyModule.cppm
export module MyModule;
#include "Config.h" // ๋งคํฌ๋ก๋ฅผ ๊ฐ์ ธ์ค๋ ค๊ณ ์๋
export void processData() {
char buffer[MAX_BUFFER_SIZE]; // ์๋ฌ ๋ฐ์ ๊ฐ๋ฅ!
// ...
}
์์ธ:
๋ชจ๋์ ๋งคํฌ๋ก๋ฅผ exportํ์ง ์์. ๋ชจ๋ ๊ฒฝ๊ณ๋ฅผ ๋์ด์ ๋งคํฌ๋ก๊ฐ ์ ํ๋์ง ์๋ ๊ฒ ์ค๊ณ ์๋์ผ!
ํด๊ฒฐ ๋ฐฉ๋ฒ:
1. ๋งคํฌ๋ก ๋์ constexpr ๋ณ์๋ enum ์ฌ์ฉ
2. ์ ๋ง ํ์ํ๋ฉด ์ ์ญ ๋ชจ๋ ํ๋๊ทธ๋จผํธ ํ์ฉ
// ๋ฐฉ๋ฒ 1: constexpr ์ฌ์ฉ (๊ถ์ฅ)
export module MyModule;
export constexpr size_t MAX_BUFFER_SIZE = 1024;
export constexpr bool DEBUG_MODE = true;
// ๋ฐฉ๋ฒ 2: ์ ์ญ ๋ชจ๋ ํ๋๊ทธ๋จผํธ (๋น๊ถ์ฅ)
module; // ์ ์ญ ๋ชจ๋ ํ๋๊ทธ๋จผํธ ์์
#include "Config.h" // ์ฌ๊ธฐ์ includeํ๋ฉด ๋งคํฌ๋ก ์ฌ์ฉ ๊ฐ๋ฅ
export module MyModule;
export void processData() {
char buffer[MAX_BUFFER_SIZE]; // ์ด์ ์๋ํจ
// ...
}
๐ ๊ณ ๊ธ ๊ธฐ๋ฒ: ๋ชจ๋ ํํฐ์ ๋ง์คํฐํ๊ธฐ
๋ชจ๋ ํํฐ์ ์ ๋๊ท๋ชจ ๋ชจ๋์ ์กฐ์งํํ๋ ๊ฐ๋ ฅํ ๋๊ตฌ์ผ. ์ ๋๋ก ํ์ฉํ๋ฉด ์ฝ๋ ๊ตฌ์กฐ๊ฐ ํจ์ฌ ๊น๋ํด์ ธ! ๐จ
๐ ํํฐ์ ์ ์ข ๋ฅ
์ธ๋ถ์ ๊ณต๊ฐ๋๋ ํํฐ์
. export import :PartitionName์ผ๋ก ์ฌexportํ ์ ์์ด.
// Graphics:Renderer.cppm - ์ธํฐํ์ด์ค ํํฐ์
export module Graphics:Renderer;
export class Renderer {
public:
void render();
void clear();
};
// Graphics.cppm - ๋ฉ์ธ ๋ชจ๋ ์ธํฐํ์ด์ค
export module Graphics;
export import :Renderer; // ์ธ๋ถ์ ๊ณต๊ฐ
export import :Shader;
export import :Texture;
๋ชจ๋ ๋ด๋ถ์์๋ง ์ฌ์ฉ๋๋ ํํฐ์ . export ์์ด import๋ง ํด.
// Graphics:Internal.cppm - ๊ตฌํ ํํฐ์
module Graphics:Internal; // export ์์!
// ๋ด๋ถ ํฌํผ ํจ์๋ค
namespace internal {
void optimizeMesh(Mesh& mesh) { /* ... */ }
void validateShader(const Shader& shader) { /* ... */ }
}
// Graphics:Renderer.cppm
export module Graphics:Renderer;
import :Internal; // ๋ด๋ถ ํํฐ์
์ฌ์ฉ
export class Renderer {
public:
void render() {
// internal ๋ค์์คํ์ด์ค ์ฌ์ฉ ๊ฐ๋ฅ
internal::optimizeMesh(currentMesh);
}
};
๐ฏ ํํฐ์ ํ์ฉ ์ ๋ต
์ ๋ต 1: ๊ธฐ๋ฅ๋ณ ํํฐ์
๊ด๋ จ๋ ๊ธฐ๋ฅ๋ผ๋ฆฌ ๋ฌถ์ด์ ํํฐ์
์ผ๋ก ๋ถ๋ฆฌ
export module Database;
export import :Connection; // ์ฐ๊ฒฐ ๊ด๋ฆฌ
export import :Query; // ์ฟผ๋ฆฌ ์คํ
export import :Transaction; // ํธ๋์ญ์
์ฒ๋ฆฌ
export import :Schema; // ์คํค๋ง ์ ์
์ ๋ต 2: ๊ณ์ธต๋ณ ํํฐ์
์ถ์ํ ์์ค์ ๋ฐ๋ผ ํํฐ์
๊ตฌ์ฑ
export module Network;
export import :LowLevel; // ์์ผ, ๋ฐ์ดํธ ์คํธ๋ฆผ
export import :Protocol; // HTTP, WebSocket ๋ฑ
export import :HighLevel; // REST API, GraphQL ํด๋ผ์ด์ธํธ
์ ๋ต 3: ํ๋ซํผ๋ณ ํํฐ์
ํ๋ซํผ ํนํ ์ฝ๋๋ฅผ ํํฐ์
์ผ๋ก ๋ถ๋ฆฌ
export module FileSystem;
#ifdef _WIN32
export import :Windows;
#elif defined(__linux__)
export import :Linux;
#elif defined(__APPLE__)
export import :MacOS;
#endif
export import :Common; // ๊ณตํต ์ธํฐํ์ด์ค
๐ ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ชจ๋ ํ์ฉํ๊ธฐ
C++23๋ถํฐ๋ ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ชจ๋๋ก ์ ๊ณต๋ผ! ์ด๊ฒ ์ผ๋ง๋ ํธํ์ง ํ๋ฒ ๋ณด์. ๐
๐ ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ชจ๋ import
// ์ ํต์ ์ธ ๋ฐฉ์ - ์๋ง์ #include
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <memory>
#include <functional>
#include <optional>
#include <variant>
// ... ๋๋ ์์ด ๊ณ์
// ๋ชจ๋ ๋ฐฉ์ - ๋จ ํ ์ค!
import std;
int main() {
std::vector<std::string> names = {"Alice", "Bob", "Charlie"};
std::ranges::sort(names);
for (const auto& name : names) {
std::cout << name << '\n';
}
}
import std; ํ๋๋ก ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ์ฒด๋ฅผ ์ฌ์ฉํ ์ ์์ด! ์ปดํ์ผ ์๊ฐ์ ์์ญ ๊ฐ์ ํค๋๋ฅผ includeํ๋ ๊ฒ๋ณด๋ค ํจ์ฌ ๋นจ๋ผ. ๐
โก ์ฑ๋ฅ ๋น๊ต: #include vs import
๊ฐ๋จํ ํ๋ก๊ทธ๋จ์์ ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ก๋ฉ ์๊ฐ์ ๋น๊ตํด๋ดค์ด:
| ๋ฐฉ์ | ์ปดํ์ผ ์๊ฐ | ์ ์ฒ๋ฆฌ ํ ์ฝ๋ ๋ผ์ธ |
|---|---|---|
| #include (10๊ฐ ํค๋) | 2.3์ด | ~50,000์ค |
| #include (30๊ฐ ํค๋) | 4.8์ด | ~150,000์ค |
| import std; | 0.8์ด | ์๋ณธ ์ฝ๋๋ง |
์ฐจ์ด๊ฐ ์์ฒญ๋์ง? ํนํ ๋๊ท๋ชจ ํ๋ก์ ํธ์์๋ ์ด ์ฐจ์ด๊ฐ ๋์ ๋ผ์ ๊ฐ๋ฐ ์์ฐ์ฑ์ ํฐ ์ํฅ์ ์ค! โฑ๏ธ
import std;๋ C++23 ๊ธฐ๋ฅ์ด์ผ. ์์ง ๋ชจ๋ ์ปดํ์ผ๋ฌ๊ฐ ์๋ฒฝํ๊ฒ ์ง์ํ์ง๋ ์์. GCC 14+, Clang 17+, MSVC 19.36+ ๋ฒ์ ์ ํ์ธํด๋ด!
๐ฏ ์ค์ ํ๋ก์ ํธ ์์ : ๊ฒ์ ์์ง ๊ตฌ์กฐ
์ด๋ก ์ ์ถฉ๋ถํ ๋ฐฐ์ ์ผ๋, ์ด์ ์ค์ ๊ฒ์ ์์ง ํ๋ก์ ํธ๋ฅผ ๋ชจ๋๋ก ๊ตฌ์กฐํํ๋ ์์ ํ ์์ ๋ฅผ ๋ณด์! ๐ฎ
๐๏ธ ํ๋ก์ ํธ ๊ตฌ์กฐ
GameEngine/
โโโ Core/
โ โโโ Math/
โ โ โโโ Vector.cppm
โ โ โโโ Matrix.cppm
โ โ โโโ Quaternion.cppm
โ โ โโโ Math.cppm
โ โโโ Memory/
โ โ โโโ Allocator.cppm
โ โ โโโ Pool.cppm
โ โ โโโ Memory.cppm
โ โโโ Core.cppm
โ
โโโ Graphics/
โ โโโ Renderer.cppm
โ โโโ Shader.cppm
โ โโโ Texture.cppm
โ โโโ Mesh.cppm
โ โโโ Graphics.cppm
โ
โโโ Physics/
โ โโโ RigidBody.cppm
โ โโโ Collision.cppm
โ โโโ Constraint.cppm
โ โโโ Physics.cppm
โ
โโโ Audio/
โ โโโ SoundEngine.cppm
โ โโโ Music.cppm
โ โโโ Audio.cppm
โ
โโโ Input/
โ โโโ Keyboard.cppm
โ โโโ Mouse.cppm
โ โโโ Input.cppm
โ
โโโ Engine.cppm
export module GameEngine.Core.Math:Vector;
import std;
export namespace GameEngine::Math {
class Vector3 {
public:
float x, y, z;
constexpr Vector3(float x = 0, float y = 0, float z = 0) noexcept
: x(x), y(y), z(z) {}
// ์ฐ์ฐ์ ์ค๋ฒ๋ก๋ฉ
constexpr Vector3 operator+(const Vector3& other) const noexcept {
return Vector3(x + other.x, y + other.y, z + other.z);
}
constexpr Vector3 operator-(const Vector3& other) const noexcept {
return Vector3(x - other.x, y - other.y, z - other.z);
}
constexpr Vector3 operator*(float scalar) const noexcept {
return Vector3(x * scalar, y * scalar, z * scalar);
}
// ๋ฒกํฐ ์ฐ์ฐ
[[nodiscard]] float length() const noexcept {
return std::sqrt(x * x + y * y + z * z);
}
[[nodiscard]] float lengthSquared() const noexcept {
return x * x + y * y + z * z;
}
[[nodiscard]] Vector3 normalized() const noexcept {
float len = length();
if (len > 0.0001f) {
return *this * (1.0f / len);
}
return Vector3(0, 0, 0);
}
[[nodiscard]] float dot(const Vector3& other) const noexcept {
return x * other.x + y * other.y + z * other.z;
}
[[nodiscard]] Vector3 cross(const Vector3& other) const noexcept {
return Vector3(
y * other.z - z * other.y,
z * other.x - x * other.z,
x * other.y - y * other.x
);
}
};
// ์ ์ญ ์ฐ์ฐ์
constexpr Vector3 operator*(float scalar, const Vector3& vec) noexcept {
return vec * scalar;
}
} // namespace GameEngine::Math
export module GameEngine.Core.Math;
// ํํฐ์
๋ค์ ์ฌexport
export import :Vector;
export import :Matrix;
export import :Quaternion;
export namespace GameEngine::Math {
// ๊ณตํต ์ํ ์์
inline constexpr float PI = 3.14159265358979323846f;
inline constexpr float TWO_PI = 2.0f * PI;
inline constexpr float HALF_PI = 0.5f * PI;
inline constexpr float DEG_TO_RAD = PI / 180.0f;
inline constexpr float RAD_TO_DEG = 180.0f / PI;
// ์ ํธ๋ฆฌํฐ ํจ์
template<typename T>
constexpr T clamp(T value, T min, T max) noexcept {
return value < min ? min : (value > max ? max : value);
}
template<typename T>
constexpr T lerp(T a, T b, float t) noexcept {
return a + (b - a) * t;
}
constexpr float degrees(float radians) noexcept {
return radians * RAD_TO_DEG;
}
constexpr float radians(float degrees) noexcept {
return degrees * DEG_TO_RAD;
}
} // namespace GameEngine::Math
export module GameEngine.Graphics:Renderer;
import GameEngine.Core.Math;
import std;
export namespace GameEngine::Graphics {
// ์ ๋ฐฉ ์ ์ธ
class Shader;
class Texture;
class Mesh;
enum class RenderMode {
Solid,
Wireframe,
Points
};
class Renderer {
public:
Renderer();
~Renderer();
// ์ด๊ธฐํ ๋ฐ ์ข
๋ฃ
bool initialize(int width, int height);
void shutdown();
// ๋ ๋๋ง ์ ์ด
void beginFrame();
void endFrame();
void clear(const Math::Vector3& color);
// ๋ ๋๋ง ์ค์
void setViewport(int x, int y, int width, int height);
void setRenderMode(RenderMode mode);
// ์นด๋ฉ๋ผ ์ค์
void setViewMatrix(const Math::Matrix4x4& view);
void setProjectionMatrix(const Math::Matrix4x4& projection);
// ๋ ๋๋ง
void drawMesh(const Mesh& mesh, const Shader& shader);
void drawMeshInstanced(const Mesh& mesh, const Shader& shader, int count);
// ํต๊ณ
struct Statistics {
uint32_t drawCalls;
uint32_t triangles;
uint32_t vertices;
float frameTime;
};
[[nodiscard]] const Statistics& getStatistics() const noexcept {
return stats;
}
void resetStatistics() noexcept {
stats = Statistics{};
}
private:
struct Impl;
std::unique_ptr<Impl> pImpl;
Statistics stats;
RenderMode currentMode;
};
} // namespace GameEngine::Graphics
export module GameEngine;
// ๋ชจ๋ ์๋ธ์์คํ
export
export import GameEngine.Core;
export import GameEngine.Graphics;
export import GameEngine.Physics;
export import GameEngine.Audio;
export import GameEngine.Input;
import std;
export namespace GameEngine {
class Engine {
public:
static Engine& getInstance() {
static Engine instance;
return instance;
}
bool initialize();
void shutdown();
void run();
void stop();
[[nodiscard]] bool isRunning() const noexcept {
return running;
}
// ์๋ธ์์คํ
์ ๊ทผ
[[nodiscard]] Graphics::Renderer& getRenderer() noexcept {
return *renderer;
}
[[nodiscard]] Physics::PhysicsWorld& getPhysics() noexcept {
return *physics;
}
[[nodiscard]] Audio::SoundEngine& getAudio() noexcept {
return *audio;
}
private:
Engine() = default;
~Engine() = default;
Engine(const Engine&) = delete;
Engine& operator=(const Engine&) = delete;
bool running = false;
std::unique_ptr<Graphics::Renderer> renderer;
std::unique_ptr<Physics::PhysicsWorld> physics;
std::unique_ptr<Audio::SoundEngine> audio;
};
} // namespace GameEngine
import GameEngine;
import std;
int main() {
using namespace GameEngine;
// ์์ง ์ด๊ธฐํ
auto& engine = Engine::getInstance();
if (!engine.initialize()) {
std::cerr << "Failed to initialize engine\n";
return 1;
}
// ๋ ๋๋ฌ ์ค์
auto& renderer = engine.getRenderer();
renderer.setRenderMode(Graphics::RenderMode::Solid);
// ๊ฒ์ ์ค๋ธ์ ํธ ์์ฑ
Math::Vector3 position(0, 0, 0);
Math::Vector3 velocity(1, 0, 0);
// ๋ฉ์ธ ๋ฃจํ
while (engine.isRunning()) {
renderer.beginFrame();
renderer.clear(Math::Vector3(0.1f, 0.1f, 0.15f));
// ๊ฒ์ ๋ก์ง
position = position + velocity * 0.016f; // 60 FPS ๊ฐ์
// ๋ ๋๋ง
// ... ์ค์ ๋ ๋๋ง ์ฝ๋
renderer.endFrame();
// ํต๊ณ ์ถ๋ ฅ
const auto& stats = renderer.getStatistics();
if (stats.drawCalls > 0) {
std::cout << std::format("Draw calls: {}, Triangles: {}, Frame time: {:.2f}ms\n",
stats.drawCalls, stats.triangles, stats.frameTime);
}
}
engine.shutdown();
return 0;
}
์ด๋ ๊ฒ ๊ตฌ์กฐํํ๋ฉด ๊ฐ ๋ชจ๋์ด ๋ช ํํ ์ฑ ์์ ๊ฐ์ง๊ณ , ์์กด์ฑ๋ ๊น๋ํ๊ฒ ๊ด๋ฆฌ๋ผ. ์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ๊ฑฐ๋ ๊ธฐ์กด ์ฝ๋๋ฅผ ์์ ํ ๋๋ ์ํฅ ๋ฒ์๊ฐ ์ต์ํ๋์ง! ๐ฏ
๐ ์ฑ๋ฅ ์ธก์ ๊ณผ ์ต์ ํ
๋ชจ๋์ ๋์ ํ๋ค๋ฉด ์ค์ ๋ก ์ฑ๋ฅ์ด ๊ฐ์ ๋๋์ง ์ธก์ ํด์ผ ํด. ์ด๋ป๊ฒ ์ธก์ ํ๊ณ ์ต์ ํํ ์ ์์๊น? ๐
โฑ๏ธ ์ปดํ์ผ ์๊ฐ ์ธก์
GCC/Clang:
# ์๊ฐ ์ธก์ ๊ณผ ํจ๊ป ๋น๋
time make -j8
# ๋ ์์ธํ ์ ๋ณด
g++ -ftime-report main.cpp
# ๋ชจ๋๋ณ ์ปดํ์ผ ์๊ฐ
g++ -ftime-report -c MyModule.cppm
MSVC:
# Visual Studio์์
ํ๋ก์ ํธ ์์ฑ โ C/C++ โ ๊ณ ๊ธ โ ์ปดํ์ผ ์๊ฐ ํ์: ์
# ๋๋ ๋ช
๋ น์ค์์
cl /Bt+ /c MyModule.cppm
CMake ๋น๋ ์๊ฐ ๋ถ์:
# ๋น๋ ์๊ฐ ์ธก์
cmake --build . --target all -- -j8 VERBOSE=1 2>&1 | tee build.log
# Python ์คํฌ๋ฆฝํธ๋ก ๋ถ์
python analyze_build_time.py build.log
๐ฏ ์ต์ ํ ์ฒดํฌ๋ฆฌ์คํธ
โ
๋ชจ๋ ํฌ๊ธฐ ์ ์ ์ฑ
๋๋ฌด ํฐ ๋ชจ๋์ ์ฌ์ปดํ์ผ ์๊ฐ์ด ๊ธธ์ด์ ธ. ์ ์ ํ ํฌ๊ธฐ๋ก ๋ถํ ํ๋์ง ํ์ธ!
โ
๋ถํ์ํ import ์ ๊ฑฐ
์ฌ์ฉํ์ง ์๋ ๋ชจ๋์ importํ๋ฉด ์ปดํ์ผ ์๊ฐ๋ง ๋์ด๋. ํ์ํ ๊ฒ๋ง import!
โ
ํํฐ์
ํ์ฉ
ํฐ ๋ชจ๋์ ํํฐ์
์ผ๋ก ๋๋ ์ ๋ณ๊ฒฝ ์ํฅ ๋ฒ์๋ฅผ ์ต์ํ!
โ
ํ
ํ๋ฆฟ ์ต์ํ
ํ
ํ๋ฆฟ ์ฝ๋๋ ์ธ์คํด์คํ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ ค. ๊ผญ ํ์ํ ๊ฒฝ์ฐ๋ง ์ฌ์ฉ!
โ
์ ๋ฐฉ ์ ์ธ ํ์ฉ
ํฌ์ธํฐ๋ ์ฐธ์กฐ๋ง ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ์ ๋ฐฉ ์ ์ธ์ผ๋ก ์์กด์ฑ ์ค์ด๊ธฐ!
โ
๋ณ๋ ฌ ๋น๋
๋ชจ๋์ ๋
๋ฆฝ์ ์ผ๋ก ์ปดํ์ผ ๊ฐ๋ฅํ๋ ๋ณ๋ ฌ ๋น๋๋ก ์๊ฐ ๋จ์ถ!
โ
์ฆ๋ถ ๋น๋ ์ต์ ํ
์์ฃผ ๋ณ๊ฒฝ๋๋ ์ฝ๋์ ์์ ์ ์ธ ์ฝ๋๋ฅผ ๋ถ๋ฆฌ!
๐ฎ ๋ฏธ๋ ์ ๋ง๊ณผ ๋ฐ์ ๋ฐฉํฅ
C++20 ๋ชจ๋์ ์ด์ ์์์ผ ๋ฟ์ด์ผ. ์์ผ๋ก ์ด๋ป๊ฒ ๋ฐ์ ํ ์ง ์ดํด๋ณด์! ๐
๐ C++23๊ณผ ๊ทธ ์ดํ
ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ชจ๋ํ ์์ฑ
C++23์์๋ import std;๊ฐ ํ์คํ๋์ด. ๋ชจ๋ ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ชจ๋๋ก ์ฌ์ฉํ ์ ์์ง!
๋น๋ ์์คํ
ํตํฉ ๊ฐ์
CMake, Meson, Bazel ๋ฑ ์ฃผ์ ๋น๋ ์์คํ
์ ๋ชจ๋ ์ง์์ด ๊ณ์ ๊ฐ์ ๋๊ณ ์์ด.
ํจํค์ง ๊ด๋ฆฌ์ ํตํฉ
Conan, vcpkg ๊ฐ์ ํจํค์ง ๊ด๋ฆฌ์๊ฐ ๋ชจ๋์ ๋ค์ดํฐ๋ธ๋ก ์ง์ํ๊ธฐ ์์ํ์ด.
IDE ์ง์ ๊ฐํ
Visual Studio, CLion, VS Code ๋ฑ์์ ๋ชจ๋ ์ธํ
๋ฆฌ์ผ์ค์ ๋๋ฒ๊น
์ง์์ด ๊ณ์ ๊ฐ์ ์ค!
๐ ํ์ต ๋ฆฌ์์ค์ ์ปค๋ฎค๋ํฐ
๋ชจ๋์ ๋ ๊น์ด ๊ณต๋ถํ๊ณ ์ถ๋ค๋ฉด ์ด๋ฐ ๋ฆฌ์์ค๋ค์ ํ์ฉํด๋ด:
๊ณต์ ๋ฌธ์:
โข C++ ํ์ค ๋ฌธ์ (ISO/IEC 14882:2020)
โข cppreference.com์ ๋ชจ๋ ์น์
โข ๊ฐ ์ปดํ์ผ๋ฌ ๊ณต์ ๋ฌธ์ (GCC, Clang, MSVC)
์จ๋ผ์ธ ์ปค๋ฎค๋ํฐ:
โข r/cpp ์๋ธ๋ ๋ง
โข C++ Slack ์ํฌ์คํ์ด์ค
โข Stack Overflow์ c++-modules ํ๊ทธ
์ปจํผ๋ฐ์ค ๋ฐํ:
โข CppCon, Meeting C++, C++Now ๋ฑ์ ๋ชจ๋ ๊ด๋ จ ์ธ์
โข YouTube์ ๋ง์ ๋ฐํ ์์์ด ์ฌ๋ผ์ ์์ด!
๐ ๋ง๋ฌด๋ฆฌํ๋ฉฐ
์, ์ฌ๊ธฐ๊น์ง ์ ๋ง ๊ธด ์ฌ์ ์ด์์ด! ๐ C++20 ๋ชจ๋์ ๋ํด ๊ธฐ์ด๋ถํฐ ๊ณ ๊ธ ๊ธฐ๋ฒ๊น์ง ๋ชจ๋ ์ดํด๋ดค์ด.
ํต์ฌ์ ๋ค์ ํ๋ฒ ์ ๋ฆฌํ์๋ฉด:
1. ๋ชจ๋์ ์ปดํ์ผ ์๊ฐ์ ํ๊ธฐ์ ์ผ๋ก ์ค์ฌ์ค
ํ
์คํธ ๊ธฐ๋ฐ #include ๋์ ๋ฐ์ด๋๋ฆฌ ์ธํฐํ์ด์ค(BMI)๋ฅผ ์ฌ์ฉํ๋๊น ํจ์ฌ ๋นจ๋ผ!
2. ์ฝ๋ ๊ตฌ์กฐ๊ฐ ๋ช
ํํด์ ธ
export๋ก ๊ณต๊ฐ ์ธํฐํ์ด์ค๋ฅผ ๋ช
์ํ๊ณ , ๋ด๋ถ ๊ตฌํ์ ์๋ฒฝํ๊ฒ ์จ๊ธธ ์ ์์ด.
3. ์์กด์ฑ ๊ด๋ฆฌ๊ฐ ์ฌ์์ ธ
์ํ ์์กด์ฑ ๊ฐ์ ๊ณจ์น ์ํ ๋ฌธ์ ๋ค์ด ์์ฐ์ค๋ฝ๊ฒ ํด๊ฒฐ๋ผ.
4. ๋๊ท๋ชจ ํ๋ก์ ํธ์ ์ต์ ํ๋ผ ์์ด
๊ณ์ธต์ ๊ตฌ์กฐ, ํํฐ์
, ์ธํฐํ์ด์ค/๊ตฌํ ๋ถ๋ฆฌ ๋ฑ์ผ๋ก ์์ญ๋ง ์ค์ ์ฝ๋๋ ๊น๋ํ๊ฒ ๊ด๋ฆฌ ๊ฐ๋ฅ!
๋ฌผ๋ก ์์ง ์๋ฒฝํ์ง๋ ์์. ์ปดํ์ผ๋ฌ ์ง์์ด ๊ณ์ ๊ฐ์ ๋๊ณ ์๊ณ , ๋น๋ ์์คํ
ํตํฉ๋ ๋ฐ์ ์ค์ด์ผ. ํ์ง๋ง ๋ฐฉํฅ์ ํ์คํด. ๋ชจ๋์ C++์ ๋ฏธ๋์ผ! ๐
์ ํ๋ก์ ํธ๋ฅผ ์์ํ๋ค๋ฉด ์ฃผ์ ์์ด ๋ชจ๋์ ์ฌ์ฉํด๋ด. ๊ธฐ์กด ํ๋ก์ ํธ๋ผ๋ฉด ๋จ๊ณ์ ์ผ๋ก ๋ง์ด๊ทธ๋ ์ด์
์ ๊ณ ๋ คํด๋ณผ ๋งํด. ์ฒ์์ ๋ฏ์ค๊ฒ ์ง๋ง, ์ต์ํด์ง๋ฉด ๋ค์๋ ์๋ ๋ฐฉ์์ผ๋ก ๋์๊ฐ๊ณ ์ถ์ง ์์ ๊ฑฐ์ผ! ๐
ํน์ ๋ชจ๋ ๋์
๊ณผ์ ์์ ๋งํ๋ ๋ถ๋ถ์ด ์๋ค๋ฉด, ์ฌ๋ฅ๋ท์์ C++ ์ ๋ฌธ๊ฐ๋ค์ ๋์์ ๋ฐ๋ ๊ฒ๋ ์ข์ ๋ฐฉ๋ฒ์ด์ผ. ๊ฒฝํ ๋ง์ ๊ฐ๋ฐ์์ ์กฐ์ธ ํ๋ง๋๊ฐ ๋ฉฐ์น ๊ฐ์ ์ฝ์ง์ ์ค์ฌ์ค ์ ์๊ฑฐ๋ !
์, ์ด์ ๋น์ ์ ํ๋ก์ ํธ์ ๋ชจ๋์ ์ ์ฉํด๋ณผ ์๊ฐ์ด์ผ. ํ์ด์ ๋น์ด! ํ์ดํ
! ๐ชโจ
๐ฏ๐๐ป
Happy Coding with C++20 Modules!
๊ด๋ จ ํค์๋
๋๊ธ ์์ฑ
์ด ๊ธ์ ๋ํ ์ฌ๋ฌ๋ถ์ ์๊ฐ์ ๋ค๋ ค์ฃผ์ธ์
๋ก๊ทธ์ธ์ด ํ์ํฉ๋๋ค
๋๊ธ์ ์์ฑํ๋ ค๋ฉด ๋จผ์ ๋ก๊ทธ์ธํด์ฃผ์ธ์.
๋๊ธ 0
์ง์์ธ์ ์ฒ - ์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
- ์ ์๊ถ ๋ฐ ์์ ๊ถ: ๋ณธ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ๋ ์ AI ๊ธฐ์ ๋ก ์์ฑ๋์์ผ๋ฉฐ, ๋ํ๋ฏผ๊ตญ ์ ์๊ถ๋ฒ ๋ฐ ๊ตญ์ ์ ์๊ถ ํ์ฝ์ ์ํด ๋ณดํธ๋ฉ๋๋ค.
- AI ์์ฑ ์ปจํ ์ธ ์ ๋ฒ์ ์ง์: ๋ณธ AI ์์ฑ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ์ง์ ์ฐฝ์๋ฌผ๋ก ์ธ์ ๋๋ฉฐ, ๊ด๋ จ ๋ฒ๊ท์ ๋ฐ๋ผ ์ ์๊ถ ๋ณดํธ๋ฅผ ๋ฐ์ต๋๋ค.
- ์ฌ์ฉ ์ ํ: ์ฌ๋ฅ๋ท์ ๋ช ์์ ์๋ฉด ๋์ ์์ด ๋ณธ ์ปจํ ์ธ ๋ฅผ ๋ณต์ , ์์ , ๋ฐฐํฌ, ๋๋ ์์ ์ ์ผ๋ก ํ์ฉํ๋ ํ์๋ ์๊ฒฉํ ๊ธ์ง๋ฉ๋๋ค.
- ๋ฐ์ดํฐ ์์ง ๊ธ์ง: ๋ณธ ์ปจํ ์ธ ์ ๋ํ ๋ฌด๋จ ์คํฌ๋ํ, ํฌ๋กค๋ง, ๋ฐ ์๋ํ๋ ๋ฐ์ดํฐ ์์ง์ ๋ฒ์ ์ ์ฌ์ ๋์์ด ๋ฉ๋๋ค.
- AI ํ์ต ์ ํ: ์ฌ๋ฅ๋ท์ AI ์์ฑ ์ปจํ ์ธ ๋ฅผ ํ AI ๋ชจ๋ธ ํ์ต์ ๋ฌด๋จ ์ฌ์ฉํ๋ ํ์๋ ๊ธ์ง๋๋ฉฐ, ์ด๋ ์ง์ ์ฌ์ฐ๊ถ ์นจํด๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.
์์ง ๋๊ธ์ด ์์ต๋๋ค.