๐Ÿš€ ์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์ถ”์ƒํ™” ๊ตฌํ˜„: C++์˜ ๋งˆ๋ฒ•์„ ํ’€๋‹ค! ๐Ÿง™โ€โ™‚๏ธ

์ฝ˜ํ…์ธ  ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ - ๐Ÿš€ ์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์ถ”์ƒํ™” ๊ตฌํ˜„: C++์˜ ๋งˆ๋ฒ•์„ ํ’€๋‹ค! ๐Ÿง™โ€โ™‚๏ธ

 

 

์•ˆ๋…•ํ•˜์„ธ์š”, ์ฝ”๋”ฉ ๋งˆ๋‹ˆ์•„ ์—ฌ๋Ÿฌ๋ถ„! ์˜ค๋Š˜์€ C++์˜ ์„ธ๊ณ„์—์„œ ๊ฐ€์žฅ ํ•ซํ•œ ์ฃผ์ œ ์ค‘ ํ•˜๋‚˜์ธ "์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์ถ”์ƒํ™” ๊ตฌํ˜„"์— ๋Œ€ํ•ด ๊นŠ์ด ํŒŒํ—ค์ณ๋ณผ ๊ฑฐ์˜ˆ์š”. ์ด๊ฑฐ ์™„์ „ ๊ฐœ๋ฐœ์ž๋“ค์˜ ๋กœ๋ง ์•„๋‹ˆ๊ฒ ์–ด์š”? ใ…‹ใ…‹ใ…‹

์—ฌ๋Ÿฌ๋ถ„, ํ˜น์‹œ "์ถ”์ƒํ™”๋Š” ์ข‹์€๋ฐ, ์„ฑ๋Šฅ์ด ๋–จ์–ด์ง€๋ฉด ์–ด์ฉŒ์ง€?"๋ผ๋Š” ๊ณ ๋ฏผ ํ•ด๋ณด์‹  ์  ์žˆ๋‚˜์š”? ๊ทธ๋ ‡๋‹ค๋ฉด ์ด ๊ธ€์„ ๋๊นŒ์ง€ ์ฝ์–ด๋ณด์„ธ์š”! ์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์ถ”์ƒํ™”๋ฅผ ๋งˆ์Šคํ„ฐํ•˜๋ฉด, ์—ฌ๋Ÿฌ๋ถ„์˜ ์ฝ”๋“œ๋Š” ๋งˆ์น˜ ์žฌ๋Šฅ๋„ท์—์„œ ์ตœ๊ณ ์˜ ์žฌ๋Šฅ์„ ๋ฝ๋‚ด๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋น›๋‚  ๊ฑฐ์˜ˆ์š”! ๐Ÿ˜Ž

๐Ÿ’ก ์•Œ์“ธ์‹ ์žก: ์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์›์น™์ด๋ž€ "์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ๋น„์šฉ์„ ์ง€๋ถˆํ•˜์ง€ ์•Š๋Š”๋‹ค"๋Š” C++์˜ ํ•ต์‹ฌ ์ฒ ํ•™์ด์—์š”. ์ด๊ฒŒ ๋ฐ”๋กœ C++๋ฅผ ๊ณ ์„ฑ๋Šฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์™•์ขŒ์— ์˜ฌ๋ ค๋†“์€ ๋น„๊ฒฐ์ด์ฃ !

์ž, ์ด์ œ ๋ณธ๊ฒฉ์ ์œผ๋กœ ์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์ถ”์ƒํ™”์˜ ์„ธ๊ณ„๋กœ ๋›ฐ์–ด๋“ค์–ด๋ณผ๊นŒ์š”? ์ค€๋น„๋˜์…จ๋‚˜์š”? ๊ทธ๋Ÿผ ๊ณ ๊ณ ์”ฝ~! ๐Ÿƒโ€โ™‚๏ธ๐Ÿ’จ

๐Ÿง  ์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์ถ”์ƒํ™”๋ž€ ๋ญ์•ผ?

์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์ถ”์ƒํ™”... ์ด๋ฆ„๋ถ€ํ„ฐ ๋ญ”๊ฐ€ ์žˆ์–ด ๋ณด์ด์ฃ ? ใ…‹ใ…‹ ๊ทผ๋ฐ ๊ฑฑ์ • ๋งˆ์„ธ์š”. ์ƒ๊ฐ๋ณด๋‹ค ์–ด๋ ต์ง€ ์•Š์•„์š”!

๊ฐ„๋‹จํžˆ ๋งํ•ด์„œ, ์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์ถ”์ƒํ™”๋Š” ์ถ”์ƒํ™”๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ๋„ ์„ฑ๋Šฅ ์†์‹ค์ด ์ „ํ˜€ ์—†๋Š” ์ฝ”๋”ฉ ๊ธฐ๋ฒ•์„ ๋งํ•ด์š”. ๋งˆ์น˜ ์ผ€์ดํฌ๋ฅผ ๋จน์œผ๋ฉด์„œ ์‚ด์ด ์ฐŒ์ง€ ์•Š๋Š” ๊ฒƒ๊ณผ ๊ฐ™์ฃ . ์™„์ „ ๊ฐœ์ด๋“ ์•„๋‹ˆ์—์š”? ๐Ÿ˜†

๐Ÿฐ ๋น„์œ  ํƒ€์ž„: ์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์ถ”์ƒํ™”๋Š” ๋งˆ์น˜ ํˆฌ๋ช…ํ•œ ์ผ€์ดํฌ ์ƒ์ž ๊ฐ™์•„์š”. ์ผ€์ดํฌ(๊ธฐ๋Šฅ)๋Š” ๋ณดํ˜ธ๋˜์ง€๋งŒ, ์ƒ์ž(์ถ”์ƒํ™”) ๋•Œ๋ฌธ์— ๋ฌด๊ฒŒ(์„ฑ๋Šฅ)๊ฐ€ ๋Š˜์–ด๋‚˜์ง€ ์•Š์ฃ !

C++์—์„œ ์ด๋Ÿฐ ๋งˆ๋ฒ• ๊ฐ™์€ ์ผ์ด ์–ด๋–ป๊ฒŒ ๊ฐ€๋Šฅํ•œ ๊ฑธ๊นŒ์š”? ๊ทธ ๋น„๋ฐ€์€ ๋ฐ”๋กœ...

  • ์ปดํŒŒ์ผ๋Ÿฌ์˜ ์ตœ์ ํ™” ๋Šฅ๋ ฅ ๐Ÿง™โ€โ™‚๏ธ
  • ํ…œํ”Œ๋ฆฟ ๋ฉ”ํƒ€ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ํž˜ ๐Ÿ’ช
  • ์ธ๋ผ์ธ ํ•จ์ˆ˜์˜ ํ™œ์šฉ ๐Ÿƒโ€โ™‚๏ธ
  • ๊ทธ๋ฆฌ๊ณ  ๊ฐœ๋ฐœ์ž์˜ ์˜๋ฆฌํ•œ ์ฝ”๋“œ ์„ค๊ณ„ ๐Ÿง 

์ด ๋ชจ๋“  ์š”์†Œ๋“ค์ด ํ•ฉ์ณ์ ธ์„œ ์šฐ๋ฆฌ๋Š” ์ถ”์ƒํ™”์˜ ์ด์ ์€ ๋ˆ„๋ฆฌ๋ฉด์„œ๋„ ์„ฑ๋Šฅ์€ ๊ทธ๋Œ€๋กœ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฑฐ์˜ˆ์š”. ์™„์ „ ๊ฐœ์ด๋“์ด์ฃ ? ใ…‹ใ…‹ใ…‹

์ž, ์ด์ œ ์ด ์‹ ๊ธฐํ•œ ๊ฐœ๋…์„ ์กฐ๊ธˆ ๋” ์ž์„ธํžˆ ๋“ค์—ฌ๋‹ค๋ณผ๊นŒ์š”? ์ค€๋น„๋˜์…จ๋‚˜์š”? ๊ทธ๋Ÿผ ๊ณ ๊ณ ! ๐Ÿš€

๐Ÿ” ์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์ถ”์ƒํ™”์˜ ํ•ต์‹ฌ ์›๋ฆฌ

์ž, ์ด์ œ ์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์ถ”์ƒํ™”์˜ ํ•ต์‹ฌ ์›๋ฆฌ๋ฅผ ํŒŒํ—ค์ณ๋ณผ ์‹œ๊ฐ„์ด์—์š”! ์ด๊ฒŒ ๋ฐ”๋กœ C++์˜ ์ง„์งœ ๋งค๋ ฅ์ด์ฃ . ๋งˆ์น˜ ์žฌ๋Šฅ๋„ท์—์„œ ๊ณ ์ˆ˜๋“ค์˜ ๋น„๋ฒ•์„ ๋ฐฐ์šฐ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ํฅ๋ฏธ์ง„์ง„ํ•  ๊ฑฐ์˜ˆ์š”! ๐Ÿ˜‰

1. ์ปดํŒŒ์ผ ํƒ€์ž„ ๋‹คํ˜•์„ฑ ๐Ÿ•ฐ๏ธ

๋Ÿฐํƒ€์ž„ ๋‹คํ˜•์„ฑ? ๊ทธ๊ฑด ์ข€ ๊ตฌ์‹์ด์—์š”. ์š”์ฆ˜ ํž™ํ•œ C++ ๊ฐœ๋ฐœ์ž๋“ค์€ ์ปดํŒŒ์ผ ํƒ€์ž„ ๋‹คํ˜•์„ฑ์„ ์‚ฌ์šฉํ•œ๋‹ค๊ตฌ์š”! ใ…‹ใ…‹

๐Ÿ’ก ๊ฟ€ํŒ: ํ…œํ”Œ๋ฆฟ๊ณผ static ๋‹คํ˜•์„ฑ์„ ํ™œ์šฉํ•˜๋ฉด, ๋Ÿฐํƒ€์ž„ ์˜ค๋ฒ„ํ—ค๋“œ ์—†์ด ๋‹คํ˜•์„ฑ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์–ด์š”. ์ด๊ฒŒ ๋ฐ”๋กœ ์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ์˜ ์‹œ์ž‘!

์˜ˆ๋ฅผ ๋“ค์–ด๋ณผ๊นŒ์š”? ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ํ•œ๋ฒˆ ๋ด์ฃผ์„ธ์š”:


template <typename T>
void printValue(const T& value) {
    std::cout << value << std::endl;
}

// ์‚ฌ์šฉ ์˜ˆ
printValue(42);        // int
printValue("Hello");   // const char*
printValue(3.14);      // double

์ด ์ฝ”๋“œ์—์„œ printValue ํ•จ์ˆ˜๋Š” ์–ด๋–ค ํƒ€์ž…์ด ๋“ค์–ด์™€๋„ ์ž˜ ์ž‘๋™ํ•ด์š”. ๊ทธ๋Ÿฐ๋ฐ ์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ๊ฑด, ์ด ๋‹คํ˜•์„ฑ์ด ์ปดํŒŒ์ผ ํƒ€์ž„์— ๊ฒฐ์ •๋œ๋‹ค๋Š” ๊ฑฐ์˜ˆ์š”. ๋Ÿฐํƒ€์ž„์— ๊ฐ€์ƒ ํ•จ์ˆ˜ ํ…Œ์ด๋ธ”์„ ์ฐพ์•„๋‹ค๋‹ˆ๋Š” ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์ „ํ˜€ ์—†์ฃ !

2. ์ธ๋ผ์ธ ํ•จ์ˆ˜์˜ ๋งˆ๋ฒ• ๐ŸŽฉโœจ

์ธ๋ผ์ธ ํ•จ์ˆ˜, ๋“ค์–ด๋ณด์…จ์ฃ ? ์ด๊ฑด ์ •๋ง ๋Œ€๋‹จํ•ด์š”. ํ•จ์ˆ˜ ํ˜ธ์ถœ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์™„์ „ํžˆ ์ œ๊ฑฐํ•ด๋ฒ„๋ฆฌ๊ฑฐ๋“ ์š”!

์ธ๋ผ์ธ ํ•จ์ˆ˜๋Š” ์ปดํŒŒ์ผ๋Ÿฌ์—๊ฒŒ "์•ผ, ์ด ํ•จ์ˆ˜ ํ˜ธ์ถœํ•˜์ง€ ๋ง๊ณ  ๊ทธ๋ƒฅ ์ฝ”๋“œ๋ฅผ ์—ฌ๊ธฐ์— ๋ฐ•์•„๋„ฃ์–ด!"๋ผ๊ณ  ๋งํ•˜๋Š” ๊ฑฐ์˜ˆ์š”. ์™„์ „ ๋˜‘๋˜‘ํ•˜์ฃ ?


inline int add(int a, int b) {
    return a + b;
}

int result = add(5, 3);  // ์ปดํŒŒ์ผ๋Ÿฌ: "์˜คํ‚คdokey! int result = 5 + 3; ์œผ๋กœ ๋ฐ”๊ฟ”์ค„๊ฒŒ~"

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ•จ์ˆ˜ ํ˜ธ์ถœ์— ๋”ฐ๋ฅธ ์Šคํƒ ํ”„๋ ˆ์ž„ ์ƒ์„ฑ, ๋งค๊ฐœ๋ณ€์ˆ˜ ์ „๋‹ฌ ๋“ฑ์˜ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์‹น~ ์‚ฌ๋ผ์ ธ์š”. ์™„์ „ ๊ฐœ์ด๋“! ๐Ÿ˜Ž

3. CRTP (Curiously Recurring Template Pattern) ๐Ÿ”„

CRTP... ์ด๋ฆ„๋ถ€ํ„ฐ ๋ญ”๊ฐ€ ์žˆ์–ด ๋ณด์ด์ฃ ? ใ…‹ใ…‹ใ…‹ ์ด๊ฑด ์ •๋ง C++์˜ ์ˆจ์€ ๋ณด์„์ด์—์š”!

CRTP๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋™์  ๋‹คํ˜•์„ฑ์˜ ์ด์ ์„ ๋ˆ„๋ฆฌ๋ฉด์„œ๋„ ๊ฐ€์ƒ ํ•จ์ˆ˜ ํ˜ธ์ถœ์˜ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ์–ด์š”. ์–ด๋–ป๊ฒŒ์š”? ์ž, ์ฝ”๋“œ๋กœ ํ•œ๋ฒˆ ๋ด๋ณผ๊นŒ์š”?


template <typename Derived>
class Base {
public:
    void interface() {
        static_cast<Derived*>(this)->implementation();
    }
};

class Derived : public Base<Derived> {
public:
    void implementation() {
        std::cout << "Derived implementation" << std::endl;
    }
};

// ์‚ฌ์šฉ ์˜ˆ
Derived d;
d.interface();  // "Derived implementation" ์ถœ๋ ฅ

์ด ์ฝ”๋“œ์—์„œ Base::interface()๋Š” ์ปดํŒŒ์ผ ํƒ€์ž„์— Derived::implementation()์„ ์ง์ ‘ ํ˜ธ์ถœํ•ด์š”. ๊ฐ€์ƒ ํ•จ์ˆ˜ ํ…Œ์ด๋ธ”? ๊ทธ๋Ÿฐ ๊ฑฐ ์—†์–ด์š”! ๐Ÿ˜†

๐ŸŽญ ๋น„์œ  ํƒ€์ž„: CRTP๋Š” ๋งˆ์น˜ ์—ฐ๊ทน์˜ ์ฆ‰ํฅ ๊ณต์—ฐ ๊ฐ™์•„์š”. ๋ฐฐ์šฐ(ํŒŒ์ƒ ํด๋ž˜์Šค)๊ฐ€ ๋ฌด๋Œ€(๊ธฐ๋ณธ ํด๋ž˜์Šค)์— ์˜ฌ๋ผ๊ฐ€๋ฉด, ๋Œ€๋ณธ(์ธํ„ฐํŽ˜์ด์Šค)์€ ์žˆ์ง€๋งŒ ์‹ค์ œ ๋Œ€์‚ฌ(๊ตฌํ˜„)๋Š” ๊ทธ ์ž๋ฆฌ์—์„œ ์ฆ‰ํฅ์ ์œผ๋กœ ๊ฒฐ์ •๋˜์ฃ !

์ด๋ ‡๊ฒŒ CRTP๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, ๋Ÿฐํƒ€์ž„ ๋‹คํ˜•์„ฑ์˜ ์œ ์—ฐ์„ฑ์€ ์œ ์ง€ํ•˜๋ฉด์„œ๋„ ์„ฑ๋Šฅ์€ ์ปดํŒŒ์ผ ํƒ€์ž„ ๋‹คํ˜•์„ฑ ์ˆ˜์ค€์œผ๋กœ ๋Œ์–ด์˜ฌ๋ฆด ์ˆ˜ ์žˆ์–ด์š”. ์™„์ „ ๊ฐœ์ด๋“์ด์ฃ ? ๐Ÿ‘

4. ์ตœ์ ํ™”์— ์นœํ™”์ ์ธ ์ฝ”๋“œ ์ž‘์„ฑ ๐Ÿ› ๏ธ

๋งˆ์ง€๋ง‰์œผ๋กœ, ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ตœ์ ํ™”๋ฅผ ์ž˜ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ๋„ ์ค‘์š”ํ•ด์š”. ์ด๊ฑด ๋งˆ์น˜ ์š”๋ฆฌ์‚ฌ์—๊ฒŒ ์ข‹์€ ์žฌ๋ฃŒ๋ฅผ ์ฃผ๋Š” ๊ฒƒ๊ณผ ๊ฐ™์ฃ !

  • ๋ถˆํ•„์š”ํ•œ ๋ณต์‚ฌ๋ฅผ ํ”ผํ•˜๊ธฐ (const ์ฐธ์กฐ ์‚ฌ์šฉ)
  • ๋ถˆ๋ณ€์„ฑ(immutability) ํ™œ์šฉํ•˜๊ธฐ
  • move ์˜๋ฏธ๋ก  ํ™œ์šฉํ•˜๊ธฐ
  • constexpr ํ•จ์ˆ˜ ์‚ฌ์šฉํ•˜๊ธฐ

์ด๋Ÿฐ ๊ธฐ๋ฒ•๋“ค์„ ์‚ฌ์šฉํ•˜๋ฉด, ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์—ฌ๋Ÿฌ๋ถ„์˜ ์ฝ”๋“œ๋ฅผ ํ›จ์”ฌ ๋” ํšจ์œจ์ ์œผ๋กœ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ์žฌ๋Šฅ๋„ท์—์„œ ์ตœ๊ณ ์˜ ์ „๋ฌธ๊ฐ€์—๊ฒŒ ์กฐ์–ธ์„ ๋ฐ›๋Š” ๊ฒƒ์ฒ˜๋Ÿผ์š”! ๐Ÿ˜‰

์ž, ์ด์ œ ์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์ถ”์ƒํ™”์˜ ํ•ต์‹ฌ ์›๋ฆฌ๋ฅผ ์•Œ์•˜์œผ๋‹ˆ, ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ•˜๋Š”์ง€ ์ž์„ธํžˆ ์‚ดํŽด๋ณผ๊นŒ์š”? ๋‹ค์Œ ์„น์…˜์—์„œ ๊ณ„์†๋ฉ๋‹ˆ๋‹ค! ๐Ÿš€

๐Ÿ› ๏ธ ์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์ถ”์ƒํ™” ๊ตฌํ˜„ํ•˜๊ธฐ

์ž, ์ด์ œ ์ง„์งœ ์‹ค์ „์ด์—์š”! ์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์ถ”์ƒํ™”๋ฅผ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ•˜๋Š”์ง€ ์ž์„ธํžˆ ์•Œ์•„๋ณผ ๊ฑฐ์˜ˆ์š”. ๋งˆ์น˜ ์žฌ๋Šฅ๋„ท์—์„œ ๊ณ ์ˆ˜์˜ ๋น„๋ฒ•์„ ๋ฐฐ์šฐ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ํฅ๋ฏธ์ง„์ง„ํ•  ๊ฑฐ์˜ˆ์š”! ๐Ÿ˜‰

1. ํ…œํ”Œ๋ฆฟ์„ ํ™œ์šฉํ•œ ์ •์  ๋‹คํ˜•์„ฑ ๊ตฌํ˜„ ๐Ÿงฉ

๋จผ์ €, ํ…œํ”Œ๋ฆฟ์„ ์‚ฌ์šฉํ•ด์„œ ์ •์  ๋‹คํ˜•์„ฑ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณผ๊ฒŒ์š”. ์ด๊ฑด ์ง„์งœ C++์˜ ๊ฝƒ์ด์—์š”! ใ…‹ใ…‹


template <typename T>
class Vector {
private:
    T* data;
    size_t size;

public:
    Vector(size_t n) : data(new T[n]), size(n) {}
    
    T& operator[](size_t index) {
        return data[index];
    }
    
    size_t getSize() const {
        return size;
    }
    
    ~Vector() {
        delete[] data;
    }
};

// ์‚ฌ์šฉ ์˜ˆ
Vector<int> intVector(10);
Vector<double> doubleVector(5);

intVector[0] = 42;
doubleVector[0] = 3.14;

์ด ์ฝ”๋“œ์—์„œ Vector ํด๋ž˜์Šค๋Š” ์–ด๋–ค ํƒ€์ž…์˜ ๋ฒกํ„ฐ๋“  ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”. int๋“  double์ด๋“  ์‹ฌ์ง€์–ด ์—ฌ๋Ÿฌ๋ถ„์ด ๋งŒ๋“  ์ปค์Šคํ…€ ํƒ€์ž…์ด๋“  ์ƒ๊ด€์—†์ฃ ! ๊ทธ๋ฆฌ๊ณ  ์ด ๋ชจ๋“  ๊ฒŒ ์ปดํŒŒ์ผ ํƒ€์ž„์— ๊ฒฐ์ •๋˜๊ธฐ ๋•Œ๋ฌธ์—, ๋Ÿฐํƒ€์ž„ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์ „ํ˜€ ์—†์–ด์š”. ์™„์ „ ๊ฐœ์ด๋“! ๐Ÿ˜Ž

๐Ÿ’ก ๊ฟ€ํŒ: ํ…œํ”Œ๋ฆฟ์„ ์‚ฌ์šฉํ•˜๋ฉด ํƒ€์ž… ์•ˆ์ „์„ฑ๋„ ๋ณด์žฅ๋˜๊ณ , ์ปดํŒŒ์ผ๋Ÿฌ์˜ ์ตœ์ ํ™”๋„ ๋” ์ž˜ ์ด๋ค„์ ธ์š”. ์ผ์„์ด์กฐ๋„ค์š”!

2. CRTP๋ฅผ ํ™œ์šฉํ•œ ์ •์  ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌํ˜„ ๐ŸŽญ

CRTP(Curiously Recurring Template Pattern)๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ •์ ์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์–ด์š”. ์ด๊ฒŒ ๋ฐ”๋กœ C++์˜ ์ˆจ์€ ๋ณด์„์ด์ฃ !


template <typename Derived>
class Animal {
public:
    void makeSound() {
        static_cast<Derived*>(this)->sound();
    }
};

class Dog : public Animal<Dog> {
public:
    void sound() {
        std::cout << "Woof!" << std::endl;
    }
};

class Cat : public Animal<Cat> {
public:
    void sound() {
        std::cout << "Meow!" << std::endl;
    }
};

// ์‚ฌ์šฉ ์˜ˆ
Dog dog;
Cat cat;

dog.makeSound();  // "Woof!" ์ถœ๋ ฅ
cat.makeSound();  // "Meow!" ์ถœ๋ ฅ

์ด ์ฝ”๋“œ์—์„œ Animal::makeSound()๋Š” ๊ฐ€์ƒ ํ•จ์ˆ˜๊ฐ€ ์•„๋‹ˆ์—์š”. ๋Œ€์‹  CRTP๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ปดํŒŒ์ผ ํƒ€์ž„์— ์˜ฌ๋ฐ”๋ฅธ sound() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด์š”. ๊ฐ€์ƒ ํ•จ์ˆ˜ ํ…Œ์ด๋ธ”? ๊ทธ๋Ÿฐ ๊ฑฐ ์—†์–ด์š”! ์„ฑ๋Šฅ์€ ๊ทธ๋Œ€๋กœ, ๋‹คํ˜•์„ฑ์˜ ์ด์ ์€ ๋‹ค ๋ˆ„๋ฆฌ๋Š” ๊ฑฐ์ฃ . ์™„์ „ ๊ฐœ์ด๋“! ๐Ÿ‘

3. ์ธ๋ผ์ธ ํ•จ์ˆ˜์™€ constexpr์˜ ํ™œ์šฉ ๐Ÿš€

์ธ๋ผ์ธ ํ•จ์ˆ˜์™€ constexpr์„ ํ™œ์šฉํ•˜๋ฉด ํ•จ์ˆ˜ ํ˜ธ์ถœ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์™„์ „ํžˆ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์–ด์š”. ์ด๊ฑด ์ง„์งœ ๋งˆ๋ฒ•์ด์—์š”! ใ…‹ใ…‹ใ…‹


inline int add(int a, int b) {
    return a + b;
}

constexpr int multiply(int a, int b) {
    return a * b;
}

// ์‚ฌ์šฉ ์˜ˆ
int sum = add(5, 3);  // ์ปดํŒŒ์ผ๋Ÿฌ: "์•Œ์•˜์–ด, int sum = 5 + 3; ์œผ๋กœ ๋ฐ”๊ฟ”์ค„๊ฒŒ~"
constexpr int product = multiply(4, 7);  // ์ปดํŒŒ์ผ ํƒ€์ž„์— ๊ณ„์‚ฐ: product = 28

inline ํ‚ค์›Œ๋“œ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ์—๊ฒŒ "์ด ํ•จ์ˆ˜ ํ˜ธ์ถœํ•˜์ง€ ๋ง๊ณ  ๊ทธ๋ƒฅ ์ฝ”๋“œ๋ฅผ ์—ฌ๊ธฐ์— ๋ฐ•์•„๋„ฃ์–ด!"๋ผ๊ณ  ์ œ์•ˆํ•˜๋Š” ๊ฑฐ์˜ˆ์š”. ๊ทธ๋ฆฌ๊ณ  constexpr์€ "์ด ๊ณ„์‚ฐ์€ ์ปดํŒŒ์ผ ํƒ€์ž„์— ํ•ด์ค˜!"๋ผ๊ณ  ๋งํ•˜๋Š” ๊ฑฐ์ฃ . ๋‘˜ ๋‹ค ๋Ÿฐํƒ€์ž„ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์—†์• ๋Š” ๋ฐ ์•„์ฃผ ํšจ๊ณผ์ ์ด์—์š”!

๐ŸŽญ ๋น„์œ  ํƒ€์ž„: inline ํ•จ์ˆ˜๋Š” ๋งˆ์น˜ ๋ ˆ๊ณ  ๋ธ”๋ก ๊ฐ™์•„์š”. ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋Œ€์‹ , ๊ทธ ํ•จ์ˆ˜์˜ ์ฝ”๋“œ๋ฅผ ์ง์ ‘ ๋ผ์›Œ ๋„ฃ๋Š” ๊ฑฐ์ฃ . constexpr์€ ๋” ๋‚˜์•„๊ฐ€์„œ, ๋ ˆ๊ณ  ๋ธ”๋ก์„ ๋ฏธ๋ฆฌ ์กฐ๋ฆฝํ•ด๋†“์€ ๊ฒƒ๊ณผ ๊ฐ™์•„์š”!

4. ๋ฉ”๋ชจ๋ฆฌ ์ตœ์ ํ™”: ๋นˆ ๊ธฐ๋ณธ ํด๋ž˜์Šค ์ตœ์ ํ™” (EBCO) ํ™œ์šฉ ๐Ÿง 

C++์—๋Š” "๋นˆ ๊ธฐ๋ณธ ํด๋ž˜์Šค ์ตœ์ ํ™”"๋ผ๋Š” ๊ฒŒ ์žˆ์–ด์š”. ์ด๊ฑธ ์ž˜ ํ™œ์šฉํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์„ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์ฃ . ์–ด๋–ป๊ฒŒ ํ•˜๋Š”์ง€ ๋ณผ๊นŒ์š”?


class EmptyClass {};

template <typename T, typename Policy = EmptyClass>
class OptimizedVector : private Policy {  // private ์ƒ์†!
private:
    T* data;
    size_t size;

public:
    // ... ๋ฒกํ„ฐ์˜ ๋‚˜๋จธ์ง€ ๊ตฌํ˜„ ...
};

// ์‚ฌ์šฉ ์˜ˆ
OptimizedVector<int> vec;  // Policy๋Š” EmptyClass๋ฅผ ์‚ฌ์šฉ

์ด ์ฝ”๋“œ์—์„œ OptimizedVector๋Š” Policy๋ฅผ private ์ƒ์†๋ฐ›์•„์š”. ๋งŒ์•ฝ Policy๊ฐ€ ๋นˆ ํด๋ž˜์Šค๋ผ๋ฉด, ๋Œ€๋ถ€๋ถ„์˜ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ด๋ฅผ ์ตœ์ ํ™”ํ•ด์„œ ์ถ”๊ฐ€์ ์ธ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„์š”. ์ฆ‰, OptimizedVector์˜ ํฌ๊ธฐ๋Š” T*์™€ size_t์˜ ํฌ๊ธฐ๋งŒํผ๋งŒ ๋ฉ๋‹ˆ๋‹ค. ์™„์ „ ๊ฐœ์ด๋“์ด์ฃ ? ๐Ÿ˜Ž

5. ํƒ€์ž… ํŠน์„ฑ(Type Traits)์„ ํ™œ์šฉํ•œ ์ปดํŒŒ์ผ ํƒ€์ž„ ์ตœ์ ํ™” ๐Ÿงช

C++์˜ ํƒ€์ž… ํŠน์„ฑ์„ ํ™œ์šฉํ•˜๋ฉด ์ปดํŒŒ์ผ ํƒ€์ž„์— ์ฝ”๋“œ๋ฅผ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์–ด์š”. ์ด๊ฑด ์ง„์งœ ๊ณ ๊ธ‰ ๊ธฐ์ˆ ์ด์—์š”! ใ…‹ใ…‹


#include <type_traits>

template <typename T>
void processValue(T value) {
    if constexpr (std::is_integral_v<T>) {
        // ์ •์ˆ˜ ํƒ€์ž…์ผ ๋•Œ์˜ ์ฒ˜๋ฆฌ
        std::cout << "Processing integer: " << value << std::endl;
    } else if constexpr (std::is_floating_point_v<T>) {
        // ๋ถ€๋™์†Œ์ˆ˜์  ํƒ€์ž…์ผ ๋•Œ์˜ ์ฒ˜๋ฆฌ
        std::cout << "Processing float: " << value << std::endl;
    } else {
        // ๊ทธ ์™ธ์˜ ํƒ€์ž…์ผ ๋•Œ์˜ ์ฒ˜๋ฆฌ
        std::cout << "Processing other type" << std::endl;
    }
}

// ์‚ฌ์šฉ ์˜ˆ
processValue(42);     // "Processing integer: 42" ์ถœ๋ ฅ
processValue(3.14);   // "Processing float: 3.14" ์ถœ๋ ฅ
processValue("Hello"); // "Processing other type" ์ถœ๋ ฅ

์ด ์ฝ”๋“œ์—์„œ if constexpr์€ ์ปดํŒŒ์ผ ํƒ€์ž„์— ์กฐ๊ฑด์„ ํ‰๊ฐ€ํ•ด์š”. ์ฆ‰, ์‹ค์ œ๋กœ ์ปดํŒŒ์ผ๋œ ์ฝ”๋“œ์—๋Š” ํ•ด๋‹น ํƒ€์ž…์— ๋งž๋Š” ๋ถ„๊ธฐ๋งŒ ๋‚จ๊ฒŒ ๋˜๋Š” ๊ฑฐ์ฃ . ๋Ÿฐํƒ€์ž„์— ํƒ€์ž…์„ ์ฒดํฌํ•˜๋Š” ์˜ค๋ฒ„ํ—ค๋“œ? ๊ทธ๋Ÿฐ ๊ฑฐ ์—†์–ด์š”! ๐Ÿ˜†

๐Ÿ’ก ๊ฟ€ํŒ: ํƒ€์ž… ํŠน์„ฑ์„ ์ž˜ ํ™œ์šฉํ•˜๋ฉด, ์ œ๋„ค๋ฆญ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด์„œ๋„ ๊ฐ ํƒ€์ž…์— ์ตœ์ ํ™”๋œ ๋™์ž‘์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์–ด์š”. ์ด๊ฒŒ ๋ฐ”๋กœ C++์˜ ๊ฐ•๋ ฅํ•จ์ด์ฃ !

6. ์ด๋™ ์˜๋ฏธ๋ก (Move Semantics) ํ™œ์šฉํ•˜๊ธฐ ๐Ÿšš

C++11๋ถ€ํ„ฐ ๋„์ž…๋œ ์ด๋™ ์˜๋ฏธ๋ก ์„ ํ™œ์šฉํ•˜๋ฉด, ๋ถˆํ•„์š”ํ•œ ๋ณต์‚ฌ๋ฅผ ์ค„์ด๊ณ  ์„ฑ๋Šฅ์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์–ด์š”. ์–ด๋–ป๊ฒŒ ํ•˜๋Š”์ง€ ๋ณผ๊นŒ์š”?


class BigData {
private:
    std::vector<int> data;

public:
    BigData(std::vector<int>&& vec) : data(std::move(vec)) {}
    
    // ์ด๋™ ์ƒ์„ฑ์ž
    BigData(BigData&& other) noexcept : data(std::move(other.data)) {}
    
    // ์ด๋™ ๋Œ€์ž… ์—ฐ์‚ฐ์ž
    BigData& operator=(BigData&& other) noexcept {
        if (this != &other) {
            data = std::move(other.data);
        }
        return *this;
    }
};

// ์‚ฌ์šฉ ์˜ˆ
std::vector<int> vec = {1, 2, 3, 4, 5};
BigData bd1(std::move(vec));  // ์ด๋™ ์ƒ์„ฑ
BigData bd2 = std::move(bd1);  // ์ด๋™ ๋Œ€์ž…

์ด ์ฝ”๋“œ์—์„œ std::move๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, ๊ฐ์ฒด์˜ ๋‚ด์šฉ์„ ๋ณต์‚ฌํ•˜๋Š” ๋Œ€์‹  ์†Œ์œ ๊ถŒ๋งŒ ์ด์ „ํ•ด์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํฐ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃฐ ๋•Œ ์„ฑ๋Šฅ์ด ํฌ๊ฒŒ ํ–ฅ์ƒ๋ผ์š”. ์™„์ „ ๊ฐœ์ด๋“! ๐Ÿ‘

7. ์ปดํŒŒ์ผ๋Ÿฌ ์ตœ์ ํ™” ํžŒํŠธ ์‚ฌ์šฉํ•˜๊ธฐ ๐ŸŽฏ

C++์—๋Š” ์ปดํŒŒ์ผ๋Ÿฌ์—๊ฒŒ ์ตœ์ ํ™” ํžŒํŠธ๋ฅผ ์ค„ ์ˆ˜ ์žˆ๋Š” ํ‚ค์›Œ๋“œ๋“ค์ด ์žˆ์–ด์š”. ์ด๊ฑธ ์ž˜ ํ™œ์šฉํ•˜๋ฉด ์„ฑ๋Šฅ์„ ๋”์šฑ ๋Œ์–ด์˜ฌ๋ฆด ์ˆ˜ ์žˆ์ฃ !


void processData(const std::vector<int>& data) {
    int sum = 0;
    for (const auto& value : data) {
        if (__builtin_expect(value > 0, 1)) {  // ๋Œ€๋ถ€๋ถ„์˜ ๊ฐ’์ด ์–‘์ˆ˜์ผ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ
            sum += value;
        }
    }
    std::cout << "Sum of positive numbers: " << sum << std::endl;
}

์—ฌ๊ธฐ์„œ __builtin_expect๋Š” GCC์™€ Clang ์ปดํŒŒ์ผ๋Ÿฌ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋‚ด์žฅ ํ•จ์ˆ˜์˜ˆ์š”. ์ด ํ•จ์ˆ˜๋Š” ์ปดํŒŒ์ผ๋Ÿฌ์—๊ฒŒ "์ด ์กฐ๊ฑด์€ ๋Œ€๋ถ€๋ถ„ ์ฐธ์ผ ๊ฑฐ์•ผ"๋ผ๊ณ  ์•Œ๋ ค์ฃผ๋Š” ๊ฑฐ์ฃ . ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ด ์ •๋ณด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋” ํšจ์œจ์ ์ธ ๋ถ„๊ธฐ ์˜ˆ์ธก์„ ํ•  ์ˆ˜ ์žˆ์–ด์š”.

๐ŸŽญ ๋น„์œ  ํƒ€์ž„: ์ด๋Ÿฐ ์ตœ์ ํ™” ํžŒํŠธ๋Š” ๋งˆ์น˜ ๋‚ด๋น„๊ฒŒ์ด์…˜์— ๊ตํ†ต ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์•„์š”. ์ปดํŒŒ์ผ๋Ÿฌ(๋‚ด๋น„๊ฒŒ์ด์…˜)๊ฐ€ ๋” ํšจ์œจ์ ์ธ ์ฝ”๋“œ ๊ฒฝ๋กœ(์ตœ์  ๊ฒฝ๋กœ)๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ฃผ๋Š” ๊ฑฐ์ฃ !

์ž, ์—ฌ๊ธฐ๊นŒ์ง€ ์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์ถ”์ƒํ™”๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•๋“ค์„ ์‚ดํŽด๋ดค์–ด์š”. ์ด ๊ธฐ๋ฒ•๋“ค์„ ์ž˜ ํ™œ์šฉํ•˜๋ฉด, ์—ฌ๋Ÿฌ๋ถ„์˜ C++ ์ฝ”๋“œ๋Š” ์ถ”์ƒํ™”์˜ ์ด์ ์€ ๋ˆ„๋ฆฌ๋ฉด์„œ๋„ ์„ฑ๋Šฅ์€ ๊ทน๋Œ€ํ™”ํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”. ๋งˆ์น˜ ์žฌ๋Šฅ๋„ท์—์„œ ์ตœ๊ณ ์˜ ์‹ค๋ ฅ์ž๊ฐ€ ๋œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ด์ฃ ! ๐Ÿ˜‰

๋‹ค์Œ ์„น์…˜์—์„œ๋Š” ์ด๋Ÿฐ ๊ธฐ๋ฒ•๋“ค์„ ์‹ค์ œ ํ”„๋กœ์ ํŠธ์— ์–ด๋–ป๊ฒŒ ์ ์šฉํ•˜๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ์€ ๋ฌด์—‡์ธ์ง€ ์ž์„ธํžˆ ์•Œ์•„๋ณผ๊ฒŒ์š”. ๊ณ„์† ๋”ฐ๋ผ์˜ค์„ธ์š”! ๐Ÿš€

๐Ÿ—๏ธ ์‹ค์ œ ํ”„๋กœ์ ํŠธ์— ์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์ถ”์ƒํ™” ์ ์šฉํ•˜๊ธฐ

์ž, ์ด์ œ ์šฐ๋ฆฌ๊ฐ€ ๋ฐฐ์šด ์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์ถ”์ƒํ™” ๊ธฐ๋ฒ•๋“ค์„ ์‹ค์ œ ํ”„๋กœ์ ํŠธ์— ์–ด๋–ป๊ฒŒ ์ ์šฉํ•˜๋Š”์ง€ ์•Œ์•„๋ณผ ์ฐจ๋ก€์˜ˆ์š”. ์ด๊ฑด ๋งˆ์น˜ ์žฌ๋Šฅ๋„ท์—์„œ ๋ฐฐ์šด ๊ธฐ์ˆ ์„ ์‹ค์ „์—์„œ ์จ๋ณด๋Š” ๊ฒƒ๊ณผ ๊ฐ™์•„์š”! ๐Ÿ˜Ž

1. ๊ฒŒ์ž„ ์—”์ง„ ์ปดํฌ๋„ŒํŠธ ์‹œ์Šคํ…œ ๊ตฌํ˜„ํ•˜๊ธฐ ๐ŸŽฎ

๊ฒŒ์ž„ ์—”์ง„์—์„œ ์ปดํฌ๋„ŒํŠธ ๊ธฐ๋ฐ˜ ์•„ํ‚คํ…์ฒ˜๋ฅผ ๊ตฌํ˜„ํ•  ๋•Œ ์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์ถ”์ƒํ™”๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”. ์–ด๋–ป๊ฒŒ ํ•˜๋Š”์ง€ ๋ณผ๊นŒ์š”?


#include <vector>
#include <memory>

// ๊ธฐ๋ณธ ์ปดํฌ๋„ŒํŠธ ํด๋ž˜์Šค
class Component {
public  :
    virtual ~Component() = default;
    virtual void update() = 0;
};

// CRTP๋ฅผ ์‚ฌ์šฉํ•œ ์ปดํฌ๋„ŒํŠธ ๊ธฐ๋ณธ ํด๋ž˜์Šค
template <typename Derived>
class ComponentBase : public Component {
public:
    void update() override {
        static_cast<Derived*>(this)->updateImpl();
    }
};

// ๊ตฌ์ฒด์ ์ธ ์ปดํฌ๋„ŒํŠธ ํด๋ž˜์Šค๋“ค
class TransformComponent : public ComponentBase<TransformComponent> {
public:
    void updateImpl() {
        // ์œ„์น˜, ํšŒ์ „, ํฌ๊ธฐ ์—…๋ฐ์ดํŠธ ๋กœ์ง
    }
};

class RenderComponent : public ComponentBase<RenderComponent> {
public:
    void updateImpl() {
        // ๋ Œ๋”๋ง ๋กœ์ง
    }
};

// ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ ํด๋ž˜์Šค
class GameObject {
private:
    std::vector<std::unique_ptr<Component>> components;

public:
    template <typename T, typename... Args>
    T* addComponent(Args&&... args) {
        auto component = std::make_unique<T>(std::forward<Args>(args)...);
        T* rawPtr = component.get();
        components.push_back(std::move(component));
        return rawPtr;
    }

    void update() {
        for (auto& component : components) {
            component->update();
        }
    }
};

// ์‚ฌ์šฉ ์˜ˆ
int main() {
    GameObject player;
    player.addComponent<TransformComponent>();
    player.addComponent<RenderComponent>();
    
    // ๊ฒŒ์ž„ ๋ฃจํ”„
    for (int i = 0; i < 100; ++i) {
        player.update();
    }
    
    return 0;
}

์ด ์ฝ”๋“œ์—์„œ ์šฐ๋ฆฌ๋Š” CRTP๋ฅผ ์‚ฌ์šฉํ•ด ์ปดํฌ๋„ŒํŠธ ์‹œ์Šคํ…œ์„ ๊ตฌํ˜„ํ–ˆ์–ด์š”. ComponentBase ํด๋ž˜์Šค๋Š” ์ •์  ๋‹คํ˜•์„ฑ์„ ์ œ๊ณตํ•˜๋ฉด์„œ๋„, ๊ฐ€์ƒ ํ•จ์ˆ˜ ํ˜ธ์ถœ์˜ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค˜์š”. ์™„์ „ ๊ฐœ์ด๋“์ด์ฃ ? ๐Ÿ˜‰

๐Ÿ’ก ๊ฟ€ํŒ: ์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•˜๋ฉด, ์ปดํฌ๋„ŒํŠธ ์‹œ์Šคํ…œ์˜ ์œ ์—ฐ์„ฑ์€ ์œ ์ง€ํ•˜๋ฉด์„œ๋„ ์„ฑ๋Šฅ์€ ๊ทน๋Œ€ํ™”ํ•  ์ˆ˜ ์žˆ์–ด์š”. ํŠนํžˆ ๊ฒŒ์ž„ ์—”์ง„์ฒ˜๋Ÿผ ์„ฑ๋Šฅ์ด ์ค‘์š”ํ•œ ์‹œ์Šคํ…œ์—์„œ ์•„์ฃผ ์œ ์šฉํ•˜์ฃ !

2. ๊ณ ์„ฑ๋Šฅ ์ˆ˜ํ•™ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋งŒ๋“ค๊ธฐ ๐Ÿงฎ

์ˆ˜ํ•™ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งŒ๋“ค ๋•Œ๋„ ์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์ถ”์ƒํ™”๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”. ํ…œํ”Œ๋ฆฟ๊ณผ ์ธ๋ผ์ธ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ง์ด์ฃ !


#include <cmath>

template <typename T>
class Vector2D {
private:
    T x, y;

public:
    constexpr Vector2D(T x = 0, T y = 0) : x(x), y(y) {}

    constexpr T getX() const { return x; }
    constexpr T getY() const { return y; }

    constexpr Vector2D operator+(const Vector2D& other) const {
        return Vector2D(x + other.x, y + other.y);
    }

    constexpr Vector2D operator*(T scalar) const {
        return Vector2D(x * scalar, y * scalar);
    }

    constexpr T dot(const Vector2D& other) const {
        return x * other.x + y * other.y;
    }

    constexpr T magnitude() const {
        return std::sqrt(x * x + y * y);
    }
};

// ์‚ฌ์šฉ ์˜ˆ
int main() {
    constexpr Vector2D<float> v1(3.0f, 4.0f);
    constexpr Vector2D<float> v2(1.0f, 2.0f);

    constexpr auto v3 = v1 + v2;
    constexpr auto v4 = v1 * 2.0f;
    constexpr auto dotProduct = v1.dot(v2);
    constexpr auto mag = v1.magnitude();

    return 0;
}

์ด ์ฝ”๋“œ์—์„œ ์šฐ๋ฆฌ๋Š” constexpr์„ ์‚ฌ์šฉํ•ด ์ปดํŒŒ์ผ ํƒ€์ž„ ๊ณ„์‚ฐ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ–ˆ์–ด์š”. ๋˜ํ•œ ๋ชจ๋“  ํ•จ์ˆ˜๋ฅผ ์ธ๋ผ์ธ์œผ๋กœ ๊ตฌํ˜„ํ•ด ํ•จ์ˆ˜ ํ˜ธ์ถœ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ œ๊ฑฐํ–ˆ์ฃ . ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ˆ˜ํ•™ ์—ฐ์‚ฐ์˜ ์ถ”์ƒํ™”๋Š” ์œ ์ง€ํ•˜๋ฉด์„œ๋„ ์„ฑ๋Šฅ์€ ๊ทน๋Œ€ํ™”ํ•  ์ˆ˜ ์žˆ์–ด์š”. ์™„์ „ ๊ฐœ์ด๋“! ๐Ÿ‘

3. ๊ณ ์„ฑ๋Šฅ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์ž ๊ตฌํ˜„ํ•˜๊ธฐ ๐Ÿ’พ

๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์€ ์„ฑ๋Šฅ์— ํฐ ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ๋ถ€๋ถ„์ด์—์š”. ์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์ถ”์ƒํ™”๋ฅผ ํ™œ์šฉํ•ด ๊ณ ์„ฑ๋Šฅ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์ž๋ฅผ ๋งŒ๋“ค์–ด๋ณผ๊นŒ์š”?


#include <cstddef>
#include <new>

template <size_t BlockSize, size_t BlockCount>
class FixedAllocator {
private:
    char memory[BlockSize * BlockCount];
    bool used[BlockCount] = {false};

public:
    void* allocate(size_t size) {
        if (size > BlockSize) return nullptr;
        for (size_t i = 0; i < BlockCount; ++i) {
            if (!used[i]) {
                used[i] = true;
                return memory + (i * BlockSize);
            }
        }
        return nullptr;
    }

    void deallocate(void* ptr) {
        ptrdiff_t diff = static_cast<char*>(ptr) - memory;
        size_t index = diff / BlockSize;
        if (index < BlockCount) {
            used[index] = false;
        }
    }
};

// ์‚ฌ์šฉ ์˜ˆ
template <typename T>
class MyAllocator {
private:
    static FixedAllocator<sizeof(T), 100> allocator;

public:
    T* allocate(size_t n) {
        return static_cast<T*>(allocator.allocate(n * sizeof(T)));
    }

    void deallocate(T* p, size_t) {
        allocator.deallocate(p);
    }
};

template <typename T>
FixedAllocator<sizeof(T), 100> MyAllocator<T>::allocator;

// ์‚ฌ์šฉ ์˜ˆ
int main() {
    MyAllocator<int> alloc;
    int* p = alloc.allocate(1);
    *p = 42;
    alloc.deallocate(p, 1);
    return 0;
}

์ด ์ฝ”๋“œ์—์„œ ์šฐ๋ฆฌ๋Š” ํ…œํ”Œ๋ฆฟ์„ ์‚ฌ์šฉํ•ด ํƒ€์ž…๋ณ„๋กœ ์ตœ์ ํ™”๋œ ๊ณ ์ • ํฌ๊ธฐ ํ• ๋‹น์ž๋ฅผ ๊ตฌํ˜„ํ–ˆ์–ด์š”. ์ด ํ• ๋‹น์ž๋Š” ๋™์  ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์˜ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ํฌ๊ฒŒ ์ค„์ผ ์ˆ˜ ์žˆ์ฃ . ๊ฒŒ๋‹ค๊ฐ€ ํ…œํ”Œ๋ฆฟ์„ ์‚ฌ์šฉํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, ๋‹ค์–‘ํ•œ ํƒ€์ž…์— ๋Œ€ํ•ด ์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”. ์™„์ „ ๊ฐœ์ด๋“! ๐Ÿ˜Ž

๐ŸŽญ ๋น„์œ  ํƒ€์ž„: ์ด ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์ž๋Š” ๋งˆ์น˜ ์ž˜ ์ •๋ฆฌ๋œ ์„œ๋ž์žฅ ๊ฐ™์•„์š”. ๊ฐ ์„œ๋ž(๋ธ”๋ก)์˜ ํฌ๊ธฐ๊ฐ€ ์ •ํ•ด์ ธ ์žˆ๊ณ , ํ•„์š”ํ•  ๋•Œ๋งˆ๋‹ค ๋นˆ ์„œ๋ž์„ ๋น ๋ฅด๊ฒŒ ์ฐพ์•„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ฃ . ๊ทธ๋ฆฌ๊ณ  ๋‹ค ์“ฐ๋ฉด ๋ฐ”๋กœ ๋ฐ˜๋‚ฉ! ํšจ์œจ์ ์ด๊ณ  ๋น ๋ฅด๋‹ต๋‹ˆ๋‹ค.

์ฃผ์˜์‚ฌํ•ญ ๋ฐ ํŒ โš ๏ธ

์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์ถ”์ƒํ™”๋ฅผ ์‹ค์ œ ํ”„๋กœ์ ํŠธ์— ์ ์šฉํ•  ๋•Œ ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ๋“ค์ด ์žˆ์–ด์š”:

  1. ์ปดํŒŒ์ผ ์‹œ๊ฐ„ ์ฆ๊ฐ€: ํ…œํ”Œ๋ฆฟ์„ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋ฉด ์ปดํŒŒ์ผ ์‹œ๊ฐ„์ด ๋Š˜์–ด๋‚  ์ˆ˜ ์žˆ์–ด์š”. ๋นŒ๋“œ ์‹œ๊ฐ„๊ณผ ์„ฑ๋Šฅ ์‚ฌ์ด์˜ ๊ท ํ˜•์„ ์ž˜ ๋งž์ถฐ์•ผ ํ•ด์š”.
  2. ๋””๋ฒ„๊น…์˜ ์–ด๋ ค์›€: ์ธ๋ผ์ธ ํ•จ์ˆ˜๋‚˜ ํ…œํ”Œ๋ฆฟ์„ ๊ณผ๋„ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋ฉด ๋””๋ฒ„๊น…์ด ์–ด๋ ค์›Œ์งˆ ์ˆ˜ ์žˆ์–ด์š”. ์ ์ ˆํ•œ ๋กœ๊น…๊ณผ ์—๋Ÿฌ ์ฒ˜๋ฆฌ๋ฅผ ๊ผญ ์ถ”๊ฐ€ํ•˜์„ธ์š”.
  3. ์ฝ”๋“œ ๋ณต์žก์„ฑ ์ฆ๊ฐ€: ์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ๊ธฐ๋ฒ•๋“ค์€ ๋•Œ๋กœ ์ฝ”๋“œ๋ฅผ ๋ณต์žกํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”. ๊ฐ€๋…์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ํ•ญ์ƒ ๊ณ ๋ คํ•˜์„ธ์š”.
  4. ํ”Œ๋žซํผ ์˜์กด์„ฑ: ์ผ๋ถ€ ์ตœ์ ํ™” ๊ธฐ๋ฒ•์€ ํŠน์ • ์ปดํŒŒ์ผ๋Ÿฌ๋‚˜ ํ”Œ๋žซํผ์— ์˜์กด์ ์ผ ์ˆ˜ ์žˆ์–ด์š”. ํฌ๋กœ์Šค ํ”Œ๋žซํผ ํ˜ธํ™˜์„ฑ์„ ํ™•์ธํ•˜์„ธ์š”.

์ด๋Ÿฐ ์ ๋“ค์„ ์ฃผ์˜ํ•˜๋ฉด์„œ ์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์ถ”์ƒํ™”๋ฅผ ์ ์šฉํ•˜๋ฉด, ์—ฌ๋Ÿฌ๋ถ„์˜ C++ ํ”„๋กœ์ ํŠธ๋Š” ์„ฑ๋Šฅ๊ณผ ์ถ”์ƒํ™” ์‚ฌ์ด์˜ ์™„๋ฒฝํ•œ ๊ท ํ˜•์„ ์ด๋ฃฐ ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”. ๋งˆ์น˜ ์žฌ๋Šฅ๋„ท์—์„œ ์ตœ๊ณ ์˜ ์ „๋ฌธ๊ฐ€๊ฐ€ ๋œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ด์ฃ ! ๐Ÿ˜‰

์ž, ์ด์ œ ์—ฌ๋Ÿฌ๋ถ„์€ ์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์ถ”์ƒํ™”์˜ ์‹ค์ „ ์ ์šฉ๋ฒ•์„ ์•Œ๊ฒŒ ๋˜์—ˆ์–ด์š”. ์ด ๊ธฐ์ˆ ์„ ํ™œ์šฉํ•ด ์—ฌ๋Ÿฌ๋ถ„๋งŒ์˜ ๊ณ ์„ฑ๋Šฅ C++ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค์–ด๋ณด์„ธ์š”. ํ™”์ดํŒ…! ๐Ÿš€

๐ŸŽญ ๊ฒฐ๋ก : C++์˜ ๋งˆ๋ฒ•์‚ฌ๊ฐ€ ๋˜์–ด๋ณด์„ธ์š”!

์ž, ์—ฌ๋Ÿฌ๋ถ„! ์šฐ๋ฆฌ๋Š” ์ง€๊ธˆ๊นŒ์ง€ ์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์ถ”์ƒํ™”์˜ ์„ธ๊ณ„๋ฅผ ํƒํ—˜ํ–ˆ์–ด์š”. ์ด์ œ ์—ฌ๋Ÿฌ๋ถ„์€ C++์˜ ์ง„์ •ํ•œ ๋งˆ๋ฒ•์‚ฌ๊ฐ€ ๋  ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋‹ต๋‹ˆ๋‹ค! ๐Ÿง™โ€โ™‚๏ธโœจ

์šฐ๋ฆฌ๊ฐ€ ๋ฐฐ์šด ๋‚ด์šฉ์„ ์ •๋ฆฌํ•ด๋ณผ๊นŒ์š”?

  • ํ…œํ”Œ๋ฆฟ๊ณผ CRTP๋ฅผ ํ™œ์šฉํ•œ ์ •์  ๋‹คํ˜•์„ฑ ๊ตฌํ˜„ ๐Ÿงฉ
  • ์ธ๋ผ์ธ ํ•จ์ˆ˜์™€ constexpr์„ ์ด์šฉํ•œ ์ปดํŒŒ์ผ ํƒ€์ž„ ์ตœ์ ํ™” ๐Ÿš€
  • ์ด๋™ ์˜๋ฏธ๋ก ์„ ํ†ตํ•œ ๋ถˆํ•„์š”ํ•œ ๋ณต์‚ฌ ์ œ๊ฑฐ ๐Ÿšš
  • ํƒ€์ž… ํŠน์„ฑ๊ณผ ์ปดํŒŒ์ผ๋Ÿฌ ์ตœ์ ํ™” ํžŒํŠธ ํ™œ์šฉ ๐ŸŽฏ
  • ์‹ค์ œ ํ”„๋กœ์ ํŠธ์—์„œ์˜ ์ ์šฉ ์‚ฌ๋ก€ (๊ฒŒ์ž„ ์—”์ง„, ์ˆ˜ํ•™ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ, ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์ž) ๐Ÿ—๏ธ

์ด ๊ธฐ์ˆ ๋“ค์„ ๋งˆ์Šคํ„ฐํ•˜๋ฉด, ์—ฌ๋Ÿฌ๋ถ„์€ ์ถ”์ƒํ™”์˜ ์ด์ ์€ ๋ˆ„๋ฆฌ๋ฉด์„œ๋„ ์„ฑ๋Šฅ์€ ๊ทน๋Œ€ํ™”ํ•  ์ˆ˜ ์žˆ์–ด์š”. ๋งˆ์น˜ ์žฌ๋Šฅ๋„ท์—์„œ ์ตœ๊ณ ์˜ ์‹ค๋ ฅ์ž๊ฐ€ ๋œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ด์ฃ ! ๐Ÿ˜Ž

๐Ÿ’ก ๊ฟ€ํŒ: ์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์ถ”์ƒํ™”๋Š” ๊ฐ•๋ ฅํ•˜์ง€๋งŒ, ํ•ญ์ƒ ๊ฐ€๋…์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ๊ณ ๋ คํ•ด์•ผ ํ•ด์š”. ๋•Œ๋กœ๋Š” ์•ฝ๊ฐ„์˜ ์„ฑ๋Šฅ ์†์‹ค์„ ๊ฐ์ˆ˜ํ•˜๊ณ  ๋” ๋ช…ํ™•ํ•œ ์ฝ”๋“œ๋ฅผ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด ์ข‹์„ ์ˆ˜๋„ ์žˆ๋‹ต๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ๋ถ„, ์ด์ œ C++์˜ ๊ฐ•๋ ฅํ•œ ๋ฌด๊ธฐ๋ฅผ ์†์— ๋„ฃ์—ˆ์–ด์š”. ์ด๊ฑธ๋กœ ๋ญ˜ ๋งŒ๋“ค์–ด๋ณผ๊นŒ์š”? ์ดˆ๊ณ ์† ๊ฒŒ์ž„ ์—”์ง„? ํšจ์œจ์ ์ธ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์‹œ์Šคํ…œ? ์•„๋‹ˆ๋ฉด ์™„์ „ํžˆ ์ƒˆ๋กœ์šด ๋ญ”๊ฐ€๋ฅผ? ๊ฐ€๋Šฅ์„ฑ์€ ๋ฌดํ•œํ•ด์š”!

์ œ๋กœ ์˜ค๋ฒ„ํ—ค๋“œ ์ถ”์ƒํ™”์˜ ์„ธ๊ณ„๋Š” ๊นŠ๊ณ  ๋„“์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ๋‹ค๋ฃฌ ๋‚ด์šฉ์€ ๋น™์‚ฐ์˜ ์ผ๊ฐ์ผ ๋ฟ์ด์—์š”. ๊ณ„์†ํ•ด์„œ ๊ณต๋ถ€ํ•˜๊ณ , ์‹คํ—˜ํ•˜๊ณ , ์ƒˆ๋กœ์šด ๊ธฐ์ˆ ์„ ํƒํ—˜ํ•ด๋ณด์„ธ์š”. C++์˜ ์„ธ๊ณ„์—๋Š” ์–ธ์ œ๋‚˜ ์ƒˆ๋กœ์šด ๋ฐœ๊ฒฌ์ด ์—ฌ๋Ÿฌ๋ถ„์„ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ๋‹ต๋‹ˆ๋‹ค.

์ž, ์ด์ œ ์—ฌ๋Ÿฌ๋ถ„์˜ ์ฐจ๋ก€์˜ˆ์š”. ์ด ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ๋“ค์„ ๊ฐ€์ง€๊ณ  ์—ฌ๋Ÿฌ๋ถ„๋งŒ์˜ C++ ๋งˆ๋ฒ•์„ ๋ถ€๋ ค๋ณด์„ธ์š”. ์„ธ์ƒ์„ ๋†€๋ผ๊ฒŒ ํ•  ์ค€๋น„ ๋˜์…จ๋‚˜์š”? ๊ทธ๋Ÿผ ๊ณ ๊ณ ์”ฝ~! ๐Ÿš€

์—ฌ๋Ÿฌ๋ถ„์˜ C++ ์—ฌ์ •์— ํ–‰์šด์ด ํ•จ๊ป˜ํ•˜๊ธฐ๋ฅผ! ํ™”์ดํŒ…! ๐Ÿ’ช๐Ÿ˜„