[전문가를 위한 C++] 11장. C++의 까다롭고 유별난 부분

Chapter 11. C++의 까다롭고 유별난 부분

11.1 레퍼런스

  • 레퍼런스 변수
    • 레퍼런스 변수는 반드시 생성과 동시에 초기화 되야 한다.
      int x = 3;
      int &ref = x;
      
    • 아래와 같이 레퍼런스 변수를 클래스 밖에서 선언만 하고 초기화 하지 않으면 컴파일 에러가 발생한다.
      int &emptyRef;  // compile error
      
    • 정수 리터럴처럼 이름 없는 값에 대해서는 레퍼런스를 생성할 수 없다. 단, const 레퍼런스는 얼마든지 만들 수 있다.
      int &unnameRef1 = 5;  // compile error
      const int &unnameRef2 = 5;  // OK
      
    • 임시객체도 마찬가지로 non-const 레퍼런스는 만들 수 없지만, const 레퍼런스는 만들 수 있다.
      std::string getString() { return "Hello World!" }
      std::string &string1 = getString();  // compile error
      const std::string &string2 = getString();  // OK
      
    • (1) 레퍼런스 대상 변경하기
      • 레퍼런스는 처음 초기화 할 때 지정한 변수만 가리킨다. 레퍼런스는 한 번 생성되고 나면 가리키는 대상을 변경할 수 없다.
      • 한 번 선언된 레퍼런스에 다른 변수를 대입하면 레퍼런스 대상이 바뀌는 것이 아니라 원래 가리키던 변수의 값이 새로 대입한 변수의 값으로 바뀐다.
        int x = 3, y = 4;
        int& xRef = x;
        xRef = y;  // xRef가 y를 가리키는 것이 아니라, x의 값을 4로 변경한다.
        
      • xRef에 y의 주소를 대입하면 가리키는 대상을 바꿀 수 있을까?
        xRef = &y;  // compile error. y의 주소는 포인터이고, xRef는 int의 레퍼런스이다. 
        
      • 레퍼런스에 레퍼런스를 대입하면 가리키는 대상을 바꿀 수 있을까?
        int x = 3, y = 5;
        int &xRef = x;
        int &yRef = y;
        yRef = xRef;  // yRef가 가리키는 대상은 바뀌지 않고, y의 값이 3으로 변경된다. 
        
      • 결론 : 레퍼런스를 초기화 하고 나면 레퍼런스가 가리키는 변수를 변경할 수 없고, 그 변수의 값만 바꿀 수 있다.
    • (2) 포인터에 대한 레퍼런스와 레퍼런스에 대한 포인터
      • 레퍼런스는 모든 타입에 대해 만들 수 있다. 심지어 포인터 타입을 가리키는 레퍼런스도 만들 수 있다.
        int *intP;
        int *&ptrRef = intP;
        ptrRef = new int;
        *ptrRef = 5;  // ptrRef를 변경하면 intP가 바뀐다.
        
      • 레퍼런스가 가져온 주소는 그 레퍼런스가 가리키는 변수의 주소와 같다.
        int x = 3;
        int &xRef = x;
        int *xPtr = &xRef;  // 레퍼런스의 주소는 값에 대한 포인터와 같다. x에 대한 레퍼런스 주소를 가져와서 xPtr가 x를 가리키도록 설정한다.
        *xPtr = 100;
        
      • 레퍼런스에 대한 레퍼런스는 선언할 수 없다. 즉, int &&나 int&*와 같이 선언할 수 없다.
  • 레퍼런스 데이터 멤버
    • 레퍼런스는 어떤 변수를 가리키지 않고서는 존재할 수 없다. 따라서 레퍼런스 데이터 멤버는 반드시 생성자의 본문이 아닌 생성자 이니셜라이저에서 초기화 해야 한다.
      class MyClass {
        public:
          MyClass(int &Ref) : mRef(Ref) { }
        private:
          int &mRef;
      };
      
  • 레퍼런스 매개변수
    • const 레퍼런스
      • 레퍼런스는 기본적으로 const 속성을 가지고 있다. 다시 말해, 가리키는 대상이 절대 변하지 않는다. 그래서 명시적으로 const지정을 할 필요가 없다.
      • 레퍼런스에 대한 레퍼런스를 만들 수 없기 때문에 참조는 단 한 단계 뿐이다. 여러 단계로 참조하는 유일한 경우는 포인터에 대한 레퍼런스를 만들 때 뿐이다.
        int z;
        const int& zRef = z;
        zRef = 4;  // compile error
        

11.2 키워드 혼동

  • constexpr 키워드
    • constexpr 키워드를 사용하면 상수 표현식으로 다시 정의될 수 있다.

11.3 타입과 캐스팅

  • const_cast()
  • static_cast()
  • reinterpret_cast()
  • dynamic_cast()

11.4 스코프

11.5 어트리뷰트

11.6 사용자 정의 리터럴

11.7 헤더 파일

11.8 C 유틸리티