posted by REDFORCE 2017. 3. 23. 07:30

목차


1. Auto

2. range based for

3. enum class

4. non-static data member initializers

5. initializer lists

6. default / delete definition

7. override / final

8. emplacement

9. constexpr

10. lambda

11. random

12. thread



2. emplacement


이번 글은 emplacement에 대해서 정리해보도록 하겠습니다.


emplacement를 간단히 설명해보자면


  • 오브젝트 생성과 컨테이너 추가를 한 번에 할 수 있다.
  • STL의 대부분의 컨테이너에서 지원
    • 요소의 생성자 인수를 받아서 컨테이너 내에서 오브젝트를 만든다.
    • push_back() -> emplace_back()
    • push_front() -> emplace_front()
    • insert() -> emplace()

  • push_back 에 비해 요소 추가 비용을 줄일 수 있다.
    • 임시 오브젝트의 복사와 파괴 비용이 발생하지 않는다.


보시다시피 사용 방법은 기존 push_back 이나 insert와 동일하다.


다만 push_back이나 insert의 경우 내부적으로 값 복사가 발생하여 비용이 들었으나


emplace_back이나 emplace를 이용하면 값 복사 현상이 없어져서 더 적은 비용으로 기능을 수행할 수 있다!




어..나는 값 복사가 일어나는게 필요한대?


라고 한다면 기존 push_back이나 insert를 쓰면 된다.


posted by REDFORCE 2017. 3. 23. 06:51

목차


1. Auto

2. range based for

3. enum class

4. non-static data member initializers

5. initializer lists

6. default / delete definition

7. override / final

8. emplacement

9. constexpr

10. lambda

11. random

12. thread


이번 글에서는 [7편] override / final 에 대해서 살펴보도록 하겠습니다.


사실 override와 final은 매우 쉬운거라 딱히 한개의 글로 적기 뭐했습니다만..


블로그 분량을 늘려서 빨리 구글에 노출되야해!!!

라는 것 때문에 글을 나눈 것은 아닙니다.


7. override / final

  • override : 컴파일러에게 부모클래스의 멤버 함수를 재 정의함을 알린다.

  • final : 부모 클래스의 특정 멤버 함수를 자식 클래스에서 재정의하지 못하도록 막을 때 사용 한다.


오버라이드는 간단히 부모 클래스에 선언 된 함수를 재정의 할 때나


이미 부모클래스에 있는 함수 다시 재정의 해본다아~~? 하고 절차를 확인할 때 사용 할 수 있습니다.



위 Base에 선언 된 가상함수 foo(int i) 를 override 한 것은 잘 되지만

아래 파라미터가 float 형인 것으로 override를 시도하면 컴파일 에러가 발생하게 됩니다.


개인적으로는 override를 이용하여 내가 부모클래스에 만들어 뒀던 가상함수를 


다시 재정의하여 쓸 때 오타가 없는지 확인 하는 용도로도 썼었습니다.



간단한 예로 이렇게 활용했지요~!


Base Class 에 virtual void Update( float timeDelta);  라 만들어진 것을    // Update 가 대문자로 시작

Derived Class 에 virtual void update (float timeDelta) override;  라고 적으면 // update 가 소문자로 시작


이런식으로 적으면 바로 컴파일러가 update와 Update를 구분하여 너 철자 틀렸심. 하고 빨간줄을 그어줍니다.




두 번째 Final은 반대로 final이 선언 된 클래스를 끝으로 더이상 자식한테 재정의를 허용 하지 않을 때 사용합니다.



개인적으로는 상속을 하면서 자식으로 뻗어 나갈 때, 이 함수는 더 이상 재정의하면서 계속 썼다간


원 목적에서 완전 틀어저 버릴 거 같아...라는 생각이 들거나


팀 프로젝트에서 내 코드임 재정의하거나 건들지마셈 하고 명시할 때 붙이기도 했습니다.


posted by REDFORCE 2017. 3. 22. 23:09

목차


1. Auto

2. range based for

3. enum class

4. non-static data member initializers

5. initializer lists

6. default / delete definition

7. override / final

8. emplacement

9. constexpr

10. lambda

11. random

12. thread


이번 글에서는 [6편] dafault / delete definition 에 대해서 살펴보도록 하겠습니다.


6. default / delete


default : 컴파일러가 함수를 자동으로 생성하도록 명시적으로 지정

delete : 컴파일러가 함수를 자동으로 생성하지 않도록 명시적으로 지정


위의 코드를 살펴보면 class TEST의 생성자와 소멸자는 default로 명시를 하는 것을 볼 수 있습니다.

default로 명시가 되었기 때문에 class TEST의 내용은 컴파일러가 함수를 자동으로 생성하게 됩니다.




반대로 class TEST2는 delete로 함수들이 명시적으로 지정되어 있습니다.

그리고 생성자와 void* operator new(size_t) = delete; 가 정의되어 있는 관계로

new 연산자를 이용한 할당이 블로킹 되어 있습니다.


두 번째 예로 다음 코드를 보도록 하겠습니다.



간단히 struct 안에 func(double d) 함수 선언하고 delete로 지정을 하였습니다.

그리고 main에서 func( double d )  함수를 사용하려고 했지만!


Error가 빰빠카밤~ 하고 나오는걸 볼 수 있으실 겁니다.



아그럼 default는 자동으로 생성하는데 뭘해준다는거야?


라고 궁금해 하실까봐.

(사실 아 그냥 대충써... 하고 귀차니즘 발동하려다가 더 보충해봅니다..)


이번엔 default에 대한 예를 적어 보겠습니다.



위 코드를 보면 MyTest 클래스에서 기본적인 MyTest() 생성자가 기본으로 있습니다.

보통 기본 생성자는 우리가 따로 선언/정의를 해주지 않아도 컴파일러가 몰래 쓰담쓰담 만드는 게 상식입니다.


그렇다면 아래와 같이 코드를 바꾸면 어떻게 될까요?



당연히 기본 생성자를 직접 선언도 안했을 뿐더러 다른 생성자를 만들었기 때문에

기본 생성자가 만들어지지 않습니다.


따라서 당연히 컴파일 에러가 빠밤~ 하고 나오게 되조.


이때 편하게 쓰는게 바로 default 입니다.



default로 기본 생성자를 명시해줬기 때문에 딱히 정의를 안하더라도 컴파일러가 자동으로 생성해주게 됩니다.

이런식으로 활용하는 것이 default 입니다~



딱히 default 자체는 많이 쓸일이 없을 것 같습니다만.


delete는 유용하게 활용이 가능하겠더군요.



그럼 다음 7편에 override와 final에 대해서 뵙도록 하겠습니다~

posted by REDFORCE 2017. 3. 22. 18:19

목차


1. Auto

2. range based for

3. enum class

4. non-static data member initializers

5. initializer lists

6. default / delete definition

7. override / final

8. emplacement

9. constexpr

10. lambda

11. random

12. thread


이번 글에서는 [4-5편] non-static data member initializers 와 initializer lists


를 함께 다루도록 하겠습니다.


4, 5편 내용은 짧기 때문에 두 편을 한 글로 붙였습니다.



4. Non-static data member initializers


 - C#, Java 처럼 멤버 변수 정의와 동시에 초기 값을 할당 할 수 있다.


대체 이것이 무슨 말?? 이냐 하면


역시나 코드로 바로 보도록 하자.




위에서 private: 아래의 멤버 변수를 살펴보면


선언과 동시에 초기화가 진행 되는 것을 볼 수 있다.



옛날엔 이거 안됐다!!


근데 지금은 된다 ㅡ, .  ㅡ;


학창 시절 Java를 배웠을 때는 당연히 되던거라 게임 프로그래밍으로 넘어오면서 C++을 할 때 이게 안됐던 시기엔


어 = _=..왜안되지...원래안되나...하고 넘어갔었으나


C++11로 넘어오면서 가능해진 것으로 알고 있다.


즉 헤더에서도 멤버 변수 선언과 동시에 초기화가 가능하다!



여기까지는 다들 "뭐...음..그래...그래서...? 당연하거 아닌가?" 하고 넘어 갈 수 있다.



다시 먼저 코드를 보도록 하자.



살펴보면 private이 주석 처리 되어


멤버변수들이 접근한정자 public: 으로 바뀌게 되었고



외부에서 TEST test { 1 , "test" }; 로 초기화가 가능해졌다!


이 말인즉 public 접근이 가능한 클래스 멤버 변수가 외부에서 초기화가 바로 가능하다 라는 점이다.


이걸 잘 응용해본다면 외부 다른 클래스에서도 해당 클래스의 new로 선언함과 초기화를 바로 진행이 가능하게 만들 수 있다는 것!



그 외에도 기본적인 타입들에 대해서 initializer를 쓸 수 있다.



5. initializer lists

  • 초기화 리스트 전용 type
  • 함수의 인자, 유저 정의형, STL 컨테이너의 초기화에 사용할 수 있다.

위에서 본 initializer와 마찬가지로 STL컨테이너도 똑같이 적용시킬 수 있다.

Template을 이용한 Vector 컨테이너 초기화



일반적인 배열 초기화


(오오...auto 슨상님이 등장했다)



결론. 멤버 이니셜라이즈를 통해 초기화 구문을 쉽게 정의 할 수 있다!

posted by REDFORCE 2017. 3. 22. 17:55

목차


1. Auto

2. range based for

3. enum class

4. non-static data member initializers

5. initializer lists

6. default / delete definition

7. override / final

8. emplacement

9. constexpr

10. lambda

11. random

12. thread


이번 글에서는 [3편] enum Class 에 대해서 적어보도록 하겠습니다.


enum Class에 앞서 먼저 enum이 뭔지 알아야하니 같이 나열해보며 비교하도록 하겠습니다.


3. enum class


enum 

  • c++11의 enum은 C++03 표준과 다르게 두 종류의 enum으로 바뀌었다.
  • 강한 형 사용과 범위를 가진다.
  • 'unscoped enumeration'과 'scoped enumeration'
  • unscoped enumeration은 기존(C++03) enum과 비슷

 


위 코드를 보면 스콮이 있는 enum과 없는 enum으로 구분되어 있습니다.


scoped enumeration은 ITEMTYPE:: 이라는 네임스페이스가 따라 붙는 것을 볼 수 있습니다.

(아...영타 치기 뭔가 귀찮네요...= _=)


기존의 enum은 위에 적혀있는 ITEMTYPE:: 스페이스가 없는 enum입니다.



이게 왜 좋은거냐?


라고 이제 생각할 때가 됐는데요.



우리가 보통 enum을 헤더에 선언하여 사용하다보면 대체 이 enumeration값들이 어디에 있는 거여? 하고 햇갈리게 됩니다.


따라서 scoped enumeration 같은 경우 네임스페이스가 따라 붙기 때문에


아 거기서 썼던 enum이구만~ 하고 바로 알 수 있습니다.




그리고 위와 같이 enum class로 선언하면 네임스페이스를 붙이지 않을 경우 error를 띄우게 됩니다.


강제적으로 강한 형 사용을 강요하게 되조.


덕분에 enumeration 값이 어디에 있던 것인지 강제적으로 명시하는 코드를 작성하게 됩니다.


어떻게 보면 귀찮다~ 라고 볼 수도 있지만


향후 다시 이 코드를 봤을 때 도움이 많이 되고 유지보수에도 많은 기여를 할 거라 예상 됩니다.



그래서~ 필요하다면 쓸 수 있게 끔 타입 케스팅 자체도 지원을 하고 있습니다.




enum class 자체에 대해서는 그닥 알게 없을 수도 있으나 이런식으로 C++ enum을 쓸 수 있다를 알고 가시면 좋을 것 같습니다.


(enum Class를 활용한 뒤부터는 모든 enum을 죄다 이걸로 싸그리 바꿔버리고 있는...)



다음 글 non-static data member initializers 에서 뵐게요!

posted by REDFORCE 2017. 3. 22. 17:20

이번 글에서는 1편의 auto에 이어서


range based for에 대해서 적어보겠습니다.


목차


1. Auto

2. range based for

3. enum class

4. non-static data member initializers

5. initializer lists

6. default / delete definition

7. override / final

8. emplacement

9. constexpr

10. lambda

11. random

12. thread


2. range based for


 A. range based for?? 


번역하자면 범위 기반 For 라고 적고 단순히 이해하자면 반복문을 쉽고 안전하게 쓰기 위한 For~ 라고 보면된다.



간단한 설명

  • C++11 기능 중 'auto'와 더불어 간단하면서 유용한 기능
  • VC의 'for each'와 유사
  • 반복문을 아주 쉽고 안전하게 사용할 수 있다.
  • C++ STL의 컨테이너, 배열 등에 사용할 수 있다.


코드를 먼저 살펴보면 한눈에 이해할 수 있다.




가장 첫번째 부터 


 (1) For (일반적인)

 (2) For each

 (3) range based for  로 되어있다.


여기서 눈여겨 볼 것은 auto를 활용한 range based for 문이다.


(3)에서 결국 auto i  값이 입력받은 배열의 iterator로써 활용이 된다.


편하게 auto i 의 값이 입력받은 배열의 begin 부터 end 까지 반복 수행하게 된다.



마찬가지로 std::vector 와 같은 컨테이너에서도 활용이 가능하다.




일반적인 배열을 입력해줬던 내용대로 똑같이 컨테이너를 넣어주면 된다.




그리고 이 글에서 가장 핵심적인 부분!


1. for문에서 의도치 않은 값 복사를 피하고 싶다면?


2. 그리고 이런 range based for문을 활용하면서 값 변경을 막고 싶다면?


3. 둘 다 하고싶다면?


아래와 같이 코드를 수행하면 된다.




값 복사를 피하고 싶다면 레퍼런스를 받아오도록 하게 하면되고


값 변경을 방지하고 싶다면 const를 이용하여 막을 수 있다.


둘다 하고싶다면 위 내용 둘 다 수행하면 된다.




range based for문은 확실히 반복문을 수행하는데 편리하고 쉬운 방법이면서도 안전하게 사용을 할 수 있는 방안이다!


결론. auto 짱짱맨! |O_ o/ x 256




ps. 내가 자꾸 auto 성애자가 되는 것 같다..하앜..

posted by REDFORCE 2017. 3. 22. 15:49

글을 작성하기에 앞서 아래의 링크에 걸려있는 내용을 참조하였음을 알려드립니다.


[LINK] << Click - New Window

[slideshare] Modern C++ 프로그래머를 위한 CPP11/14 핵심  (저자: 홍배 최 교수)



평상시 공부하면서 지하철을 오갈때 할거 없으면 매번 이 슬라이드를 봤었다..

본거 또 보고 본거 또 보고...

그러나 아직도 공부하면서 스마트 포인터 같은 녀석들은 잘 써먹기가 힘든 것 같다.


-------------------------------------------------


이번 글에서는 그간 공부하면서 활용했던 Modern C++ 항목들에 대해 정리하고자 합니다.


Modern C++에 대한 정리 글은 총 12편으로 나뉘어 작성 될 예정 입니다.


목차


1. Auto

2. range based for

3. enum class

4. non-static data member initializers

5. initializer lists

6. default / delete definition

7. override / final

8. emplacement

9. constexpr

10. lambda

11. random

12. thread



이 글은 [1편] auto에 대한 내용입니다.


1. auto


auto 는 최근 개인적으로 코드를 작성할 때 iterator를 대용하는 목적으로 많이 이용하고 있는 방식이다.


 A. auto란??


auto에 대해서 간단히 설명하자면


 (1) 변수 정의 때 명시적으로 type을 지정하지 않아도 된다.

 (2) auto로 정의한 변수는 초기화할 때 type이 결정 된다.

 (3) 컴파일 타임 때 type이 결정 된다.

 (4) 템플릿 프로그래밍에 사용하면 코딩이 간편해진다.

 (5) 코드 가독성이 향상된다.

  (개인적으로 (5)번은 잘 모르겠다...개인적으로 써보면서 향상 되는건 사실이지만 남발하면.....= _=;;)



auto는 위와 같이 어느 변수타입이든 대용이 가능하다.


마치 c#의 var와 같은 느낌?


C++에는 var가 없기 때문에 위와 같이 auto를 활용할 수가 있다.



기본적으로 타입이 제한되어져서 나올 값들이라면 타입을 지정해서 쓰겠지만


string이나 char* 같은 녀석들을 리턴받고 던진다거나 빠르게 프로그래밍 해야 할 때는 auto로 받는것도 나쁘지 않을 것 같다.

(그래도 왠만하면 습관적으로 명시하여 쓰겠지만...)



위와 같이 포인터 형에 대한 것도 받아서 쓸 수가 있다.



참 편리하다...



구조체나 클래스도 마찬가지로 받을 수 있다.




그리고 본인이 개인적으로 가장 많이 활용하는 iterator의 대용이다.



정말 iterator 자체를 auto로 대용할 수 있다는 게 코드를 얼마나 많이 줄일 수 있는지는 그리고 auto를 알고 있다면


가독성이 얼마나 편해지는지 가늠 할 수 있을거라 봅니다.

(auto 짱짱맨!! |O_ o/)




 B. 일반함수의 반환 값 auto 지정에 의한 형 추론

  • C++ 14의 새로운 기능
  • 일반 함수에서도 반환 값 타임을 추론할 수 있는 기능
  • 반환 값 타입으로 auto를 사용한다.

   

위의 말 중에 반환 값 타입으로 auto를 사용한다가 무슨 말이냐면...


보통 함수의 반환 값으로 bool, int 등을 선언하여 반환 값 타입이 미리 지정하여 사용하지만..



auto를 활용하면!!


위와 같이 function 자체의 return 값을 auto 로 받아서 타입 추론형으로 반환 할 수가 있다.


이 얼마나 편하단말인가!!!

(auto 짱짱맨 |O_ o/)  x 10


근데 실제로 저렇게 반환시키는 코드를 작성해본 적은 없는거 같다.

(왜...?)


음...개인적으로 저런식으로 반환형 타입을 추론형으로 만들어버리면 


다른 클래스에서 저 함수의 리턴 타입이 auto로 나와버려서 대체 무슨 타입을 리턴하는거지? 


하고 한번더 함수를 F12 누르고 들어가게 됐었다.




꼭 필요할 땐 활용해야겠지만, 팀 프로젝트에서는 조금 자중할 필요가 있지 않을까? 하는 생각이 든다.




그리고 끝으로 auto를 사용할 땐 함수에서 리턴 타입을 동결시켜줘야 한다.


코드로 적어보자면 아래와 같다.




결론. auto 짱짱맨 |O_ o/  x 119




다음 글은 range based for에 대해서 적어보도록 하겠습니다.