Cpp Coding Standard - SWTube/Darkest-Cave GitHub Wiki

클래슀 ꡬ성

ν΄λž˜μŠ€λŠ” 기본적으둜 λ…μžμ˜ 마음으둜 μž‘μ„±ν•΄μ•Όν•œλ‹€. λŒ€λΆ€λΆ„μ˜ λ…μžλ“€μ€ 클래슀의 publicν•œ 뢀뢄을 μ‚¬μš©ν•  κ²ƒμ΄λ―€λ‘œ public이 λ¨Όμ € λ‚˜μ˜€κ³  λ‚˜μ„œ protected, private 순으둜 λ‚˜μ™€μ•Όν•œλ‹€.

μ €μž‘κΆŒ ν‘œμ‹œ

λͺ¨λ“  μ†ŒμŠ€νŒŒμΌ(.h, .cpp λ“±)은 λ°˜λ“œμ‹œ 첫번째 쀄에 μ €μž‘κΆŒ ν‘œμ‹œλ₯Ό ν•΄μ•Όν•œλ‹€:

/*!
 * Copyright (c) 2021 SWTube. All rights reserved.
 * Licensed under the GPL-3.0 License. See LICENSE file in the project root for license information.
 */

λͺ…λͺ… κ·œμΉ™

기본적으둜 λ³€μˆ˜, λ©”μ„œλ“œ, ν΄λž˜μŠ€λ“€μ˜ 이름은 λͺ…ν™•ν•΄μ•Όν•˜κ³ , ꡬ체적이며, μ• λ§€ν•΄μ„œλŠ” μ•ˆλœλ‹€. ν΄λž˜μŠ€κ°€ 널리 쓰이면 쓰일 수둝 더 μ’‹κ³  ꡬ체적인 이름을 μ‚¬μš©ν•˜λΌ. μ€„μž„λ§μ€ κ±°λ₯΄λŠ” 것이 μ’‹λ‹€.

  1. ν΄λž˜μŠ€μ™€ ꡬ쑰체의 이름은 파슀칼 ν‘œκΈ°λ²•μ„ λ”°λ₯Έλ‹€

    class PlayerManager;
    struct AnimationInfo;
  2. 지역 λ³€μˆ˜ 그리고 ν•¨μˆ˜μ˜ 맀개 λ³€μˆ˜μ˜ 이름은 카멜 ν‘œκΈ°λ²•μ„ λ”°λ₯Έλ‹€

    void SomeMethod(const int someParameter)
    {
        int someNumber;
        int id;
    }
  3. λ©”μ„œλ“œ λ˜λŠ” ν•¨μˆ˜ 이름은 λ™μ‚¬λ‘œ μ‹œμž‘ν•œλ‹€.

    1. public λ©”μ„œλ“œμ˜ 이름은 파슀칼 ν‘œκΈ°λ²•μ„ λ”°λ₯Έλ‹€

      public:
          void DoSomething();
    2. κ·Έ μ™Έ λ‹€λ₯Έ λ©”μ„œλ“œμ˜ 이름은 카멜 ν‘œκΈ°λ²•μ„ λ”°λ₯Έλ‹€

      private:
          void doSomething();
  4. 절차(λ°˜ν™˜κ°’μ΄ μ—†λŠ” ν•¨μˆ˜)λŠ” λ°˜λ“œμ‹œ λͺ…ν™•ν•œ 의미λ₯Ό κ°–λŠ” 타동사와 λͺ©μ μ–΄λ₯Ό μ‚¬μš©ν•œλ‹€. λ‹€λ§Œ, ν•΄λ‹Ή ν•¨μˆ˜κ°€ 클래슀의 λ©”μ„œλ“œμ΄κΈ° λ•Œλ¬Έμ— λ¬Έλ§₯상 νƒ€λ™μ‚¬μ˜ λͺ©μ μ–΄κ°€ λΆ„λͺ…ν•  λ•ŒλŠ” μ˜ˆμ™Έλ‘œ ν•œλ‹€

  5. λΆˆλ¦¬μ–Έν˜•μ„ λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜μ˜ 경우 μ§ˆλ¬Έμ„ ν•˜λŠ” ν˜•μ‹μœΌλ‘œ μž‘μ„±ν•œλ‹€

    bool IsVisible();
    bool ShouldClearBuffer();
  6. ν•¨μˆ˜μ˜ 이름은 λ°˜λ“œμ‹œ λ°˜ν™˜ν•˜λŠ” 것이 μ–΄λ–€ 의미λ₯Ό κ°–λŠ”μ§€λ₯Ό μ•Œ 수 μžˆλ„λ‘ μ§€μ–΄μ•Όν•œλ‹€

    // μ²΄ν¬ν•΄μ„œ trueλ©΄ λ­” 뜻인데?
    bool CheckTea(FTea Tea);
    
    // μ•„~ trueλ©΄ μ°¨κ°€ freshν•˜λ‹¨ 뜻이ꡰ
    bool IsTeaFresh(FTea Tea);
  7. μƒμˆ˜ λ˜λŠ” #define으둜 μ •μ˜λœ μƒμˆ˜μ˜ 이름은 λͺ¨λ‘ λŒ€λ¬Έμžλ‘œ ν•˜λ˜ λ°‘μ€„λ‘œ 각 단어λ₯Ό λΆ„λ¦¬ν•œλ‹€

    	constexpr int SOME_CONSTANT = 1;
  8. λ„€μž„μŠ€νŽ˜μ΄μŠ€λŠ” λͺ¨λ‘ μ†Œλ¬Έμžλ‘œ μž‘μ„±ν•œλ‹€

    namespace abc{};
  9. λΆ€μšΈ(boolean)ν˜• λ³€μˆ˜λŠ” μ•žμ— bλ₯Ό 뢙인닀

    bool bFired;    // 지역 λ³€μˆ˜μ™€ public 멀버 λ³€μˆ˜μ˜ 경우
    bool mbFired;   // 클래슀의 private 멀버 λ³€μˆ˜μ˜ 경우
  10. μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ„ μ–Έν•  λ•ŒλŠ” μ•žμ— Iλ₯Ό 뢙인닀

    class ISomeInterface;
  11. μ—΄κ±°ν˜•μ„ μ„ μ–Έν•  λ•ŒλŠ” μ•žμ— eλ₯Ό 뢙인닀

    enum class eDirection
    {
        North,
        South
    };
  12. 클래슀 멀버 λ³€μˆ˜ λͺ…은 μ•žμ— m을 뢙인닀

    class Employee
    {
    protected:
    	int mDepartmentID;
    private:
    	int mAge;
    };
  13. goto λ ˆμ΄λΈ” λͺ…은 λͺ¨λ‘ λŒ€λ¬Έμžλ‘œ ν•˜λ˜ λ°‘μ€„λ‘œ 각 단어λ₯Ό λΆ„λ¦¬ν•œλ‹€

    goto MY_LABEL;
    
    // ...
    
    MY_LABEL:
        std::cout << "Magic! << std::endl;
        return 0;
  14. 값을 λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜μ˜ 이름은 무엇을 λ°˜ν™˜ν•˜λŠ”μ§€ μ•Œ 수 있게 μ§“λŠ”λ‹€

  15. λ‹¨μˆœνžˆ λ°˜λ³΅λ¬Έμ— μ‚¬μš©λ˜λŠ” λ³€μˆ˜κ°€ μ•„λ‹Œ κ²½μš°μ—” i, e 같은 λ³€μˆ˜λͺ… λŒ€μ‹  index, employee처럼 λ³€μˆ˜μ— μ €μž₯λ˜λŠ” 데이터λ₯Ό ν•œ λˆˆμ— μ•Œμ•„λ³Ό 수 μžˆλŠ” λ³€μˆ˜λͺ…을 μ‚¬μš©ν•œλ‹€.

  16. 뒀에 좔가적인 단어가 μ˜€μ§€ μ•ŠλŠ” 경우 μ€„μž„λ§μ€ λͺ¨λ‘ λŒ€λ¬Έμžλ‘œ ν‘œκΈ°ν•œλ‹€

    int OrderID;
    int HttpCode;
  17. κ΅¬μ‘°μ²΄λŠ” 였직 public 멀버 λ³€μˆ˜λ§Œ κ°€μ§ˆ 수 μžˆλ‹€. ꡬ쑰체의 멀버 λ³€μˆ˜λͺ…은 파슀칼 ν‘œκΈ°λ²•μ„ λ”°λ₯΄λ©°, ꡬ쑰체 μ•ˆμ—μ„œλŠ” ν•¨μˆ˜λŠ” μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”λ‹€

  18. μž¬κ·€ ν•¨μˆ˜λŠ” 이름 뒀에 Recursiveλ₯Ό 뢙인닀

    void FibonacciRecursive();
  19. 파일 이름은 λŒ€μ†Œλ¬ΈμžκΉŒμ§€ ν¬ν•¨ν•΄μ„œ λ°˜λ“œμ‹œ 클래슀 이름과 μΌμΉ˜ν•΄μ•Ό ν•œλ‹€

    class PlayerAnimation;
    
    PlayerAnimation.cpp
    PlayerAnimation.h
  20. μ—¬λŸ¬ 파일이 ν•˜λ‚˜μ˜ 클래슀λ₯Ό 이룰 λ•Œ, 파일 이름은 클래슀 μ΄λ¦„μœΌλ‘œ μ‹œμž‘ν•˜κ³ , κ·Έ 뒀에 밑쀄과 μ„ΈλΆ€ ν•­λͺ© 이름을 뢙인닀

    class RenderWorld;
    
    RenderWorld_load.cpp
    RenderWorld_demo.cpp
    RenderWorld_portals.cpp
  21. Reverse OOP νŒ¨ν„΄μ„ μ‚¬μš©ν•  λ•Œ, ν”Œλž«νΌ μ „μš© ν΄λž˜μŠ€λŠ” μœ„ ν•­λͺ©κ³Ό λΉ„μŠ·ν•œ λͺ…λͺ… κ·œμΉ™μ„ μ‚¬μš©ν•œλ‹€

    class Renderer;
    
    Renderer.h			// κ²Œμž„μ—μ„œ ν˜ΈμΆœλ˜λŠ” λͺ¨λ“  Renderer μΈν„°νŽ˜μ΄μŠ€
    Renderer.cpp		// λͺ¨λ“  ν”Œλž«νΌ 용 Renderer κ΅¬ν˜„ μ†ŒμŠ€
    Renderer_gl.h		// Rendererκ°€ ν˜ΈμΆœν•˜λŠ” RendererGL μΈν„°νŽ˜μ΄μŠ€
    Renderer_gl.cpp		// RendererGL κ΅¬ν˜„ μ†ŒμŠ€
  22. λΉ„νŠΈ ν”Œλž˜κ·Έ μ—΄κ±°ν˜•μ€ 이름 뒀에 Flagsλ₯Ό 뢙인닀

    enum class eVisibilityFlags
    {
    }
  23. λ³€μˆ˜ 가리기(variable shadowing)은 ν—ˆμš©λ˜μ§€ μ•ŠλŠ”λ‹€. μ™ΈλΆ€ λ³€μˆ˜κ°€ λ™μΌν•œ 이름을 μ‚¬μš© 쀑이라면 λ‚΄λΆ€ λ³€μˆ˜μ—λŠ” λ‹€λ₯Έ 이름을 μ‚¬μš©ν•œλ‹€

    class SomeClass
    {
    public:
        int32_t Count;
    public:
        void Func(const int32_t Count)
        {
            for (int32_t count = 0; count != 10; ++count)
            {
                // Use Count
            }
        }
    }

κ°€μ΄λ“œλΌμΈ

  1. 클래슀 멀버 λ³€μˆ˜μ— μ ‘κ·Όν•  λ•ŒλŠ” 항상 setter와 getterλ₯Ό μ‚¬μš©ν•œλ‹€

    • ν‹€λ¦° 방식:

      class Employee
      {
      public:
      	string Name;
      };
    • μ˜¬λ°”λ₯Έ 방식:

      class Employee
      {
      public:
      	const string& GetName() const;
      	void SetName(const string& name);
      private:
      	string mName;
      };
  2. μ™ΈλΆ€ 헀더 νŒŒμΌμ„ μΈν΄λ£¨λ“œ ν•  λ•ŒλŠ” #include <>을 μ‚¬μš©, 자체적으둜 λ§Œλ“  헀더 νŒŒμΌμ„ μΈν΄λ£¨λ“œ ν•  λ•ŒλŠ” #include ""λ₯Ό μ‚¬μš©ν•œλ‹€.

  3. μ™ΈλΆ€ 헀더 νŒŒμΌμ„ λ¨Όμ € μΈν΄λ£¨λ“œν•œ λ’€, λ‚΄λΆ€ 헀더 νŒŒμΌμ„ μΈν΄λ£¨λ“œλ₯Ό ν•  λ•Œ, κ°€λŠ₯ν•˜λ‹€λ©΄ μ•ŒνŒŒλ²³ μˆœμ„œλ₯Ό λ”°λ₯Έλ‹€

  4. λͺ¨λ“  헀더 파일 첫 번째 쀄에 #pragma onceλ₯Ό κΈ°μž¬ν•œλ‹€

  5. 지역 λ³€μˆ˜λ₯Ό μ„ μ–Έν•  λ•ŒλŠ” κ·Έ 지역 λ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ” μ½”λ“œμ™€ λ™μΌν•œ 쀄(μŠ€μ½”ν”„)에 μ„ μ–Έν•˜λŠ” 것을 μ›μΉ™μœΌλ‘œ ν•œλ‹€

  6. double이 λ°˜λ“œμ‹œ ν•„μš”ν•œ κ²½μš°κ°€ μ•„λ‹Œ 이상 뢀동 μ†Œμˆ˜μ  값에 fλ₯Ό λΆ™μ—¬μ€€λ‹€

    float f = 0.5f;
  7. switch case λ¬Έμ—λŠ” 항상 defaultλ₯Ό λ„£λŠ”λ‹€

  8. switch case λ¬Έ 끝에 break;λ₯Ό 넣지 μ•Šκ³  κ·Έ λ°”λ‘œ μ•„λž˜ case 문의 μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜κ³  싢은 경우, 미리 μ •μ˜ν•΄λ‘” FALLTHROUGH 맀크둜λ₯Ό μΆ”κ°€ν•œλ‹€. 단, case λ¬Έ μ•ˆμ— μ½”λ“œκ°€ μ—†λŠ” κ²½μš°λŠ” μ˜ˆμ™Έμ΄λ‹€. μ΄λŠ” C++17 μ‚¬μ–‘μ—μ„œ [[fallthrough]] μ• νŠΈλ¦¬λ·°νŠΈλ‘œ λŒ€μ²΄λ  것이닀.

    • C++17 이전

      switch (number)
      {
      case 0:
          DoSomething();
          FALLTHROUGH
      case 1:
          DoFallthrough();
          break;
      case 2:
      case 3:
          DoNotFallthrough();
          break;
      default:
          break;
      }
    • C++17 이후

      switch (number)
      {
      case 0:
          DoSomething();
          [[fallthrough]];
      case 1:
          DoFallthrough();
          break;
      case 2:
      case 3:
          DoNotFallthrough();
          break;
      default:
          break;
      }
  9. default caseκ°€ μ ˆλŒ€ 싀행될 일이 μ—†λŠ” 경우, default case μ•ˆμ— Assert(false);λž€ μ½”λ“œλ₯Ό μΆ”κ°€ν•œλ‹€. Assert()λŠ” 직접 κ΅¬ν˜„ν•˜λ©΄ κ·Έ μ•ˆμ—μ„œ 릴리즈 λΉŒλ“œ μ‹œ μ΅œμ ν™” 힌트λ₯Ό μΆ”κ°€ν•  수 μžˆλ‹€

    switch (type)
    {
    case 1:
        ... 
        break;
    default:
        Assert(false, "unknown type");
        break;
    }
  10. μ›μΉ™μ μœΌλ‘œ λͺ¨λ“  곳에 constλ₯Ό μ‚¬μš©ν•œλ‹€. μ—¬κΈ°μ—λŠ” 지역 λ³€μˆ˜μ™€ ν•¨μˆ˜ 맀개 λ³€μˆ˜λ„ ν¬ν•¨ν•œλ‹€

  11. 개체λ₯Ό μˆ˜μ •ν•˜μ§€ μ•ŠλŠ” 멀버 ν•¨μˆ˜μ—λŠ” λͺ¨λ‘ constλ₯Ό 뢙인닀

    int GetAge() const;
  12. κ°’(value) ν˜•μ‹μ˜ λ³€μˆ˜λ₯Ό const둜 λ°˜ν™˜ν•˜μ§€ μ•ŠλŠ”λ‹€. ν¬μΈν„°λ‚˜ μ°Έμ‘°(reference)λ₯Ό λ°˜ν™˜ν•  κ²½μš°μ—λ§Œ const λ°˜ν™˜μ„ ν•œλ‹€

  13. 클래슀 μ•ˆμ—μ„œ 멀버 λ³€μˆ˜μ™€ λ©”μ„œλ“œμ˜ λ“±μž₯ μˆœμ„œλŠ” λ‹€μŒμ„ λ”°λ₯Έλ‹€

    1. friend ν΄λž˜μŠ€λ“€
    2. public λ©”μ„œλ“œλ“€
    3. protected λ©”μ„œλ“œλ“€
    4. private λ©”μ„œλ“œλ“€
    5. protected λ³€μˆ˜λ“€
    6. private λ³€μˆ˜λ“€
  14. λŒ€λΆ€λΆ„μ˜ 경우 ν•¨μˆ˜ μ˜€λ²„λ‘œλ”©μ„ ν”Όν•œλ‹€

    • ν‹€λ¦° 방식

      const Anim* GetAnim(const int index) const;
      const Anim* GetAnim(const char* name) const;
    • μ˜¬λ°”λ₯Έ 방식

      const Anim* GetAnimByIndex(const int index) const;
      const Anim* GetAnimByName(const char* name) const;
  15. const λ°˜ν™˜μ„ μœ„ν•œ ν•¨μˆ˜ μ˜€λ²„λ‘œλ”©μ€ ν—ˆμš©ν•œλ‹€

    Anim* GetAnimByIndex(const int index);
    const Anim* GetAnimByIndex(const int index) const;
  16. const_castλ₯Ό μ§μ ‘μ μœΌλ‘œ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”λ‹€. λŒ€μ‹  const인 개제츨 μˆ˜μ • κ°€λŠ₯ν•œ ν˜•νƒœλ‘œ λ³€ν™˜ν•΄μ„œ λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜λ₯Ό λ§Œλ“ λ‹€

  17. ν΄λž˜μŠ€λŠ” 각각 λ…λ¦½λœ μ†ŒμŠ€ νŒŒμΌμ— μžˆμ–΄μ•Ό ν•œλ‹€. 단, μž‘μ€ 클래슀 λͺ‡ 개λ₯Ό ν•œ νŒŒμΌμ— 같이 λ„£μ–΄ λ‘λŠ” 것이 상식적일 경우 μ˜ˆμ™Έλ₯Ό ν—ˆμš©ν•œλ‹€

  18. ν‘œμ€€ C assert λŒ€μ‹ μ— μžμ‹ λ§Œμ˜ Assert 버전을 κ΅¬ν˜„ν•œλ‹€

  19. νŠΉμ • 쑰건이 λ°˜λ“œμ‹œ μΆ©μ‘±λ˜μ–΄μ•Ό ν•œλ‹€κ³  κ°€μ •(assertion)ν•˜κ³  μ§  μ½”λ“œ λͺ¨λ“  곳에 assertλ₯Ό μ‚¬μš©ν•œλ‹€. AssertλŠ” 볡ꡬ λΆˆκ°€λŠ₯ν•œ 쑰건이닀. AssertλŠ” 릴리즈 λΉŒλ“œμ—μ„œ [__assume](https://docs.microsoft.com/en-us/cpp/intrinsics/assume?view=msvc-160) ν‚€μ›Œλ“œλ‘œ λŒ€μ²΄ν•˜μ—¬ μ»΄νŒŒμΌλŸ¬μ— μ΅œμ ν™” 힌트λ₯Ό 쀄 수 μžˆλ‹€

  20. λͺ¨λ“  λ©”λͺ¨λ¦¬ 할당은 직접 κ΅¬ν˜„ν•œ New, Delete ν‚€μ›Œλ“œλ₯Ό 톡해 ν˜ΈμΆœν•œλ‹€

  21. memeset, memcpy, memmove와 같은 λ©”λͺ¨λ¦¬ μ—°μ‚° μ—­μ‹œ 우리 고유의 MemSet, MemCpy, MemMove ν‚€μ›Œλ“œλ₯Ό 톡해 ν˜ΈμΆœν•΄μ•Ό ν•œλ‹€

  22. μ–΄λ–€ μ΄μœ λ‘œλ“  λ§€κ°œλ³€μˆ˜λ‘œ nullptrκ°€ λ„˜μ–΄μ˜¬ 수 μžˆλŠ” κ²½μš°κ°€ μ•„λ‹ˆλΌλ©΄ 포인터 λŒ€μ‹  참쑰자(&)λ₯Ό μ‚¬μš©ν•˜λŠ” 것을 μ›μΉ™μœΌλ‘œ ν•œλ‹€ (μ˜ˆμ™ΈλŠ” λ‹€μŒ ν•­λͺ©μ„ μ°Έκ³ )

  23. ν•¨μˆ˜μ—μ„œ λ§€κ°œλ³€μˆ˜λ₯Ό 톡해 값을 λ°˜ν™˜ν•  λ•Œ(out λ§€κ°œλ³€μˆ˜)λŠ” 포인터λ₯Ό μ‚¬μš©ν•˜λ©°, λ§€κ°œλ³€μˆ˜ 이름 μ•žμ— out을 뢙인닀

    • ν•¨μˆ˜

      void GetScreenDimension(uint32_t* const outWidth, uint32_t* const  outHeight)
      {
      }
    • 호좜

      uint32_t width;
      uint32_t height;
      GetScreenDimension(&width, &height);
  24. μœ„ ν•­λͺ©μ˜ out λ§€κ°œλ³€μˆ˜λŠ” λ°˜λ“œμ‹œ null이 μ•„λ‹ˆμ–΄μ•Ό ν•œλ‹€ (ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ ifλ¬Έ λŒ€μ‹  assertλ₯Ό μ‚¬μš©ν•  것)

    void GetScreenDimension(uint32_t* const outWidth, uint32_t* const  outHeight)
    {
        Assert(outWidth);
        Assert(outHeight);
    }
  25. λ§€κ°œλ³€μˆ˜κ°€ 클래슀 λ‚΄λΆ€μ—μ„œ μ €μž₯될 λ•ŒλŠ” 포인터λ₯Ό μ‚¬μš©ν•œλ‹€

    void AddMesh(Mesh* const mesh)
    {
        mMeshCollection.push_back(mesh);
    }
  26. λ§€κ°œλ³€μˆ˜κ°€ void 포인터야 ν•˜λŠ” κ²½μš°λŠ” 포인터λ₯Ό μ‚¬μš©ν•œλ‹€

    void Update(void* const something)
    {
    }
  27. νŠΉμ • 크기(예λ₯Ό λ“€μ–΄ 데이터 λ©€λ²„μ˜ 직렬화λ₯Ό μœ„ν•œ 크기)κ°€ ν•„μš”ν•˜μ§€ μ•Šμ€ ν•œ μ—΄κ±°ν˜•μ— 크기 μ§€μ •μžλ₯Ό μΆ”κ°€ν•˜μ§€ μ•ŠλŠ”λ‹€

    enum class eDirection : uint8_t
    {
        North,
        South
    }
  28. λ””ν΄νŠΈ 맀개 λ³€μˆ˜ λŒ€μ‹  ν•¨μˆ˜ μ˜€λ²„λ‘œλ”©μ„ μ„ ν˜Έν•œλ‹€

  29. λ””ν΄νŠΈ 맀개 λ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ” 경우, nullptrλ‚˜ false, 0 같이 λΉ„νŠΈ νŒ¨ν„΄μ΄ 0인 값을 μ‚¬μš©ν•œλ‹€

  30. κ°€λŠ₯ν•œ κ³ μ •λœ 크기(size)의 μ»¨ν…Œμ΄λ„ˆλ₯Ό μ‚¬μš©ν•œλ‹€

  31. 동적 μ»¨ν…Œμ΄λ„ˆλ₯Ό μ‚¬μš©ν•΄μ•Ό ν•œλ‹€λ©΄ κ°€λŠ₯ν•œ ν•œ 미리 `reserve()``λ₯Ό ν˜ΈμΆœν•œλ‹€.

  32. #define으둜 μ •μ˜λœ μƒμˆ˜λŠ” 항상 κ΄„ν˜Έλ‘œ 감싸쀀닀

    #define NUM_CLASSES (1)
  33. μƒμˆ˜λŠ” #define보닀 const μƒμˆ˜ λ³€μˆ˜λ‘œ μ„ μ–Έν•œλ‹€

  34. 클래슀λ₯Ό μƒν˜Έ μ°Έμ‘°ν•  λ•ŒλŠ” #include보닀 μ „λ°©μ„ μ–Έ(forward declaration)을 μ΅œλŒ€ν•œ μ΄μš©ν•œλ‹€

  35. λͺ¨λ“  컴파일러 κ²½κ³ λŠ” λ°˜λ“œμ‹œ κ³ μΉœλ‹€

  36. ν•œ 쀄에 λ³€μˆ˜ ν•˜λ‚˜λ§Œ μ„ μ–Έν•œλ‹€

    • ν‹€λ¦° 방식

      int counter = 0, index = 0;
    • μ˜¬λ°”λ₯Έ 방식

      int counter = 0;
      int index = 0;
    • μ΄λž˜μ•Ό 각 λ³€μˆ˜μ— λŒ€ν•΄ 주석을 남겨 이 λ³€μˆ˜κ°€ μ–΄λ–€ μ˜λ―ΈμΈμ§€λ₯Ό μ•Œλ €μ€„ 수 있기 λ•Œλ¬Έμ΄λ‹€

  37. 지역 객체λ₯Ό λ°˜ν™˜ν•  λ•Œ NRVO의 이점을 ν™œμš©ν•œλ‹€. μ΄λŠ” ν•¨μˆ˜ 내에 ν•˜λ‚˜μ˜ returnλ¬Έ 만 μ“΄λ‹€λŠ” 것을 μ˜λ―Έν•˜λ©°, 이것은 κ°’μœΌλ‘œ 객체λ₯Ό λ°˜ν™˜ν•  λ•Œλ§Œ μ μš©λœλ‹€.

  38. structλ‚˜ classμ—μ„œ μ΄ˆκΈ°ν™” ν›„ κ°’ 변경을 λ§‰μœΌλ €κ³  const 멀버 λ³€μˆ˜λ₯Ό 쓰지 μ•ŠλŠ”λ‹€. μ°Έμ‘°(&) λ©€λ²„λ³€μˆ˜μ˜ κ²½μš°λ„ λ§ˆμ°¬κ°€μ§€

  39. 멀버 λ³€μˆ˜λ₯Ό μ΄ˆκΈ°ν™”ν•  λ•ŒλŠ” μ΄ˆκΈ°ν™” 리슀트λ₯Ό μ‚¬μš©ν•˜λŠ” 것을 기본으둜 ν•œλ‹€

λͺ¨λ˜ C++ κ°€μ΄λ“œλΌμΈ

  1. 컴파일 도쀑 assertion이 ν•„μš”ν•˜λ‹€λ©΄ static_assertλ₯Ό μ‚¬μš©ν•œλ‹€

  2. override와 final ν‚€μ›Œλ“œλ₯Ό λ°˜λ“œμ‹œ μ‚¬μš©ν•œλ‹€

  3. 항상 enum classλ₯Ό μ‚¬μš©ν•œλ‹€

    enum class eDirection
     {
         North,
         South
     }
  4. κ°€λŠ₯ν•œ Assert λŒ€μ‹  static_assert λ₯Ό μ‚¬μš©ν•œλ‹€.

  5. 포인터에 NULL λŒ€μ‹  nullptr λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

  6. 개체의 수λͺ…이 클래슀 λ‚΄μ—μ„œλ§Œ μ²˜λ¦¬λ˜λŠ” 경우 unique_ptr λ₯Ό μ‚¬μš©ν•œλ‹€. (즉, 개체 생성은 μƒμ„±μžμ—μ„œ, 개체 νŒŒκ΄΄λŠ” μ†Œλ©Έμžμ—μ„œ)

  7. 적용 κ°€λŠ₯ν•œ 곳이라면 λ²”μœ„κΈ°λ°˜ for 문을 μ‚¬μš©ν•œλ‹€.

  8. λ°˜λ³΅μžλ‚˜ new ν‚€μ›Œλ“œκ°€ 같은 쀄에 μžˆμ–΄μ„œ, μ–΄λ–€ κ°œμ²΄κ°€ λ§Œλ“€μ–΄μ§€λŠ” 지 λͺ…ν™•ν•˜κ²Œ λ“œλŸ¬λ‚˜λŠ” κ²½μš°κ°€ μ•„λ‹ˆλΌλ©΄ auto ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”λ‹€.

  9. std::moveλ₯Ό μ‚¬μš©ν•˜μ—¬ μˆ˜λ™μœΌλ‘œ λ°˜ν™˜ 값을 μ΅œμ ν™”ν•˜μ§€ μ•ŠλŠ”λ‹€. 이럴 경우, μžλ™ NRVO μ΅œμ ν™”κ°€ μ μš©λ˜μ§€ μ•ŠλŠ”λ‹€.

  10. 이동 μƒμ„±μž(move constructor)와 이동 λŒ€μž… μ—°μ‚°μž(move assignment operator)λ₯Ό μ‚¬μš©ν•΄λ„ λœλ‹€.

  11. λ‹¨μˆœ μƒμˆ˜ λ³€μˆ˜μ—λŠ” const λŒ€μ‹  constexpr μ„ μ‚¬μš©ν•œλ‹€.

    적용 μ „:

    const int DEFAULT_BUFFER_SIZE = 65536;
    
    

    적용 ν›„:

    constexpr int DEFAULT_BUFFER_SIZE = 65536;
    
  12. λžŒλ‹€ ν•¨μˆ˜μ˜ 경우 sort λ“±μ˜ ν•¨μˆ˜μ— λ§€κ°œλ³€μˆ˜λ‘œ μ „λ‹¬ν•˜λŠ” 등이 μ•„λ‹ˆλΌλ©΄ μ§€μ–‘ν•˜λŠ” 것이 μ’‹μœΌλ©°, μ‚¬μš©ν•˜λ”λΌλ„ 길이가 κ³Όλ„ν•˜κ²Œ κΈΈμ–΄μ„œλŠ” μ•ˆλœλ‹€

μ½”λ“œ ν¬λ§·νŒ…

  1. include μ „μ²˜λ¦¬λ¬Έ 블둝과 μ½”λ“œ λ³Έλ¬Έ 사이에 λ°˜λ“œμ‹œ 빈 쀄이 μžˆμ–΄μ•Ό ν•œλ‹€

  2. νƒ­(tab)은 λΉ„μ£Όμ–Ό μŠ€νŠœλ””μ˜€ 기본값을 μ‚¬μš©ν•˜λ©°, λΉ„μ£Όμ–Ό μŠ€νŠœλ””μ˜€λ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šμ„ μ‹œ 띄어쓰기 4칸을 νƒ­μœΌλ‘œ μ‚¬μš©ν•œλ‹€.

  3. μ€‘κ΄„ν˜Έ( { )λ₯Ό μ—΄ λ•ŒλŠ” μ–Έμ œλ‚˜ μƒˆλ‘œμš΄ 쀄에 μ—°λ‹€.

  4. μ€‘κ΄„ν˜Έ μ•ˆ( { } )에 μ½”λ“œκ°€ ν•œ μ€„λ§Œ μžˆλ”λΌλ„ λ°˜λ“œμ‹œ μ€‘κ΄„ν˜Έλ₯Ό μ‚¬μš©ν•œλ‹€.

     if (bSomething)
     {
         return;
     }
  5. if - else 블둝을 μ‚¬μš©ν•  경우 elseλŠ” if의 μ€‘κ΄„ν˜Έ λ‹€μŒ μ€„μ—μ„œλΆ€ν„° μž‘μ„±ν•œλ‹€

    if (bHaveUnrealLicense)
    {
        InsertYourGameHere();
    }
    else
    {
        CallMarkRein();
    }
  6. ν¬μΈν„°λ‚˜ μ°Έμ‘° κΈ°ν˜ΈλŠ” μžλ£Œν˜•μ— 뢙인닀.

     int& number;
     int* number;
  7. μ΄ˆκΈ°ν™” 리슀트λ₯Ό μ΄μš©ν•΄ 멀버 λ³€μˆ˜λ₯Ό μ΄ˆκΈ°ν™”ν•  λ•ŒλŠ” μ•„λž˜μ™€ 같은 포맷을 따라 ν•œ 쀄에 λ³€μˆ˜ ν•˜λ‚˜μ”© μ΄ˆκΈ°ν™”ν•œλ‹€.

    • ν‹€λ¦° 방식:
     MyClass::MyClass(const int var1, const int var2)
       :mVar1(var1), mVar2(var2), mVar3(0)
     {
    • μ˜¬λ°”λ₯Έ 방식:
     MyClass::MyClass(const int var1, const int var2)
       : mVar1(var1)
       , mVar2(var2)
       , mVar3(0)
     {

λΉ„μ£Όμ–Ό μŠ€νŠœλ””μ˜€ κ΄€λ ¨

  1. Visual C++: ν”„λ‘œμ νŠΈ 섀정을 λ³€κ²½ν•˜λ €λ©΄ 항상 속성 μ‹œνŠΈ(property sheets)μ—μ„œ λ³€κ²½ ν•œλ‹€.
  2. ν”„λ‘œμ νŠΈ μ„€μ •μ—μ„œ 컴파일 κ²½κ³ λ₯Ό λΉ„ν™œμ„±ν™” ν•˜μ§€ μ•ŠλŠ”λ‹€. κ·Έ λŒ€μ‹ , μ½”λ“œμ—μ„œ #pragma λ₯Ό μ‚¬μš©ν•œλ‹€.

ν™•μž₯μ„± κ΄€λ ¨

<stdint>에 μ •μ˜λœ C++11 이후 μΆ”κ°€λœ ν˜•λ“€μ„ μ‚¬μš©ν•œλ‹€

  • bool : λΆˆλ¦¬μ–Έν˜• (bool의 크기λ₯Ό μ ˆλŒ€λ‘œ μΆ”μ •ν•΄μ„œλŠ” μ•ˆλœλ‹€).
  • TODO(캐릭터 κ΄€λ ¨ μΆ”κ°€ ν•„μš”)
  • uint8_t : λ¬΄λΆ€ν˜Έ λ°”μ΄νŠΈ (1 λ°”μ΄νŠΈ).
  • int8_t : μœ λΆ€ν˜Έ λ°”μ΄νŠΈ (1 λ°”μ΄νŠΈ).
  • uint16_t : λ¬΄λΆ€ν˜Έ "λ‹¨μ •μˆ˜short" (2 λ°”μ΄νŠΈ).
  • int16_t : μœ λΆ€ν˜Έ "λ‹¨μ •μˆ˜short" (2 λ°”μ΄νŠΈ).
  • uint23_t : λ¬΄λΆ€ν˜Έ μ •μˆ˜ (4 λ°”μ΄νŠΈ).
  • int32_t : μœ λΆ€ν˜Έ μ •μˆ˜ (4 λ°”μ΄νŠΈ).
  • uint64_t : λ¬΄λΆ€ν˜Έ "4λ°° 단어quad word" (8 λ°”μ΄νŠΈ). (Microsoft의 Window.h에 WORDλΌλŠ” 16λΉ„νŠΈ λ¬΄λΆ€ν˜Έ μ •μˆ˜μ˜ 4λ°° 크기λ₯Ό κ°–μŒμ„ 의미)
  • int64_t : μœ λΆ€ν˜Έ "4λ°° 단어quad words" (8 λ°”μ΄νŠΈ).
  • float : 단정밀도 κ³ μ • μ†Œμˆ˜μ  (4 λ°”μ΄νŠΈ).
  • double : 2배정밀도 κ³ μ • μ†Œμˆ˜μ  (8 λ°”μ΄νŠΈ).

주석 κ°€μ΄λ“œλΌμΈ

  1. μ• μ΄ˆμ— μ½”λ“œ μžμ²΄κ°€ documentκ°€ 될 수 있게 μž‘μ„±ν•˜λΌ

    // Bad:
    t = s + l - b;
    
    // Good:
    TotalLeaves = SmallLeaves + LargeLeaves - SmallAndLargeLeaves;
  2. μ˜λ―ΈμžˆλŠ” 주석을 μž‘μ„±ν•˜μž

    // Bad:
    // increment Leaves
    ++Leaves;
    
    // Good:
    // we know there is another tea leaf
    ++Leaves;
  3. μ½”λ“œλ₯Ό μ œλŒ€λ‘œ λͺ» μ§  거에 주석을 넣어주지 말라. 차라리 λ‹€μ‹œ μ½”λ“œλ₯Ό 짜라.

    // Bad:
    // total number of leaves is sum of
    // small and large leaves less the
    // number of leaves that are both
    t = s + l - b;
    
    // Good:
    TotalLeaves = SmallLeaves + LargeLeaves - SmallAndLargeLeaves;
  4. μ½”λ“œμ™€ λ‚΄μš©μ΄ μƒλ°˜λ˜μ–΄μ„œλŠ” μ•ˆλœλ‹€

    // Bad:
    // never increment Leaves!
    ++Leaves;
    
    // Good:
    // we know there is another tea leaf
    ++Leaves;
⚠️ **GitHub.com Fallback** ⚠️