Publish:

태그: , ,

카테고리:


🤯 언리얼을 하기 위해 C++ 기억 되살리기 프로젝트

새로운 키워드 (C++11~) / auto

c++11부터 새로운 기능 및 키워드들이 등장했다.

  • auto
  • static_assert
  • default/delete
  • final/override

1. auto 키워드

  • 데이터형을 자동으로 추론해준다.
  • JavaScript 등의 언어에 있는 동적인 형(type)과는 다름.
    • JavaScript는 실행 중에 형이 막 바뀜
    • JavaScript에선
      1
      2
      3
      
      var x;
      x = "Chris";
      x = 50;
      

      이렇게 짤 수 있음.

  • c++에서 실제 자료형은 컴파일하는 동안 결정됨
  • 따라서, 반드시 auto 변수는 초기화 해줘야 함
    • auto x; // 에러
    • auto x = 3; // ok

2. auto로 포인터 받기

  • auto를 사용하여 포인터와 참조를 받을 수 있다.
    • 포인터를 받을 때: auto 또는 auto*
    • 참조를 받을 때: auto&
      • 참조는 반드시 &를 붙여야 한다!
1
2
3
4
// Main.cpp

Cat* myCat = new Cat("Coco", 2);            
auto myCatPtr = myCat;                          // myCat과 동일한 포인터이다.

💡 왜 같을까?
auto* 아니고 auto라고 써있지만, 컴파일러는 이미 myCat이 포인터라는 걸 첫번째 줄에서 알고 있음.
역참조 안했으니까 얜 포인터구나~ 자동으로 알아봐 줌.
하지만 가독성을 위해 *를 붙여 주자…

3. auto로 참조 받기

1
2
3
4
5
6
7
8
// Main.cpp

Cat myCat("Coco", 2);
Cat& myCatRef = myCat;

auto anotherMyCatRef = myCatRef;                // myCat에 대한 참조가 아님!!!

auto& anotherMyCatRef = myCatRef;               // myCat에 대한 참조임. 모두 다 같은 myCat의 주소.
  • auto로 참조도 받을 수 있다면, 받는 게 참조인지 값인지 컴파일러가 구분할 수 없음
    • auto a = b; <- 참조일까 복사일까? 구분 못함
  • 그래서 &를 붙여야 함

4. auto로 const 받기

1
2
3
const int b = 1;
auto& a = b;                    // 이 경우에도 auto가 const를 이어 받음.
                                // 그래서 b를 참조하지만 const 임.

5. auto 함수 반환형

  • auto 키워드는 함수가 반환하는 걸 저장하는 데에 때론 유용함
  • 함수 반환형이 변해도 auto는 그대로 쓸 수 있으니까
1
2
3
4
5
6
7
8
9
10
11
12
13
// MyMath.h
float Add(float a, float b)             // 나중에 반환형이 double로 바뀌어도
{                                       // 어차피 main()에서 result는 auto니까
    return a + b;                       // 문제 없이 반환값 받을 수 있음.
}

// Main.cpp
int main()
{
    auto result = Add(10.0, 10.0);      // 위에서 설명한대로!

    return 0;
}

💡 auto 키워드가 타이핑을 좀 줄여 주긴 함 그렇지만 가독성을 떨어뜨림 (아래 코드 예시)

1
2
3
4
5
6
7
8
9
auto minValue = object.GetMinValue();       
if (minValue < -3)
{
    // ...
}

// 위 코드에서 만약 GetMinValue가 반환하는 게 unsigned 라면?
// if 문에 들어오지 못할 것...
// 이런식으로 가독성이 안좋음

6. 반복자 대체하기, 템플릿형 받기

6-1. 반복자에는 auto 키워드가 매우 유용

1
2
3
4
5
6
7
8
9
10
11
  for (std::vector<int>::const_iterator it = v.begin(); it != v.end(); ++it)
  {
    // ...
  }

  // 위의 코드를 간단하게 줄일 수 있음

  for (auto it = v.begin(); it != v.end(); ++it)
  {
    // ...
  }

6-2. 이런 경우엔?

1
2
3
4
5
6
7
8
9
10
11
  for (std::map<std::string, std::string>::const_iterator it = v.begin(); it != v.end(); ++it)
  {
    // ...
  }

  // 당연히 가능함!

  for (auto it = v.begin(); it != v.end(); ++it)
  {
    // ...
  }

6-3. 일부 템플릿형의 경우에도 마찬가지

1
2
3
  MyArray<int>* a = new MyArray<int>(10);

  auto* a = new MyArray<int>(10);

이슈 및 공부한 것을 기록해두는 개인 블로그 입니다. 댓글, 피드백 환영합니다 🙂

Update:

댓글남기기