포인터에 대한 깊이 있는 설명은 얇은 책 한권은 나올만한 분량일 것이다. 여기서는 간략히 Modern C++에서 추가된 개념에 대해서만 정리하자. 전통적인 포인터 사용법외에 두가지 중요한 포인터 관리 크래스가 추가되었다.




포인터 연산에서 뺄셈은 가능하다. 그 뺄셈은 두 포인터 주소의 차이를 포인터의 크기로 나눈 것인테 ptrdiff_t 형이 추가 되었다. 결국 이것은 내부적으로는 int64나 int형이 재정의된 것이다. 어떤 특별한 장점이 있다기 보다는 포인터의 차이값이란 의미를 강조하기 위한 것으로 보인다.



uniq_ptr 클래스가 추가되었다. 포인터를 유일하게 관리하는 클래스이며 scope를 벗어나면 자동으로 메모리에서 해제가 된다.

라인 15, 16 : 명시적으로 선언하여 메모리를 할당하기 보다는 make_unique를 통해 하는 것을 권장하고 있다. 사실 라인 15에서 선언하는 방식이 문제가 있는 것은 아니지만 함수의 인자로 선언하면서 동시에 할당할 경우 문제를 일을킬 수 있다고 한다. 가급적 라인 16의 방식으로 사용하도록 하자.


라인 20: get 함수를 이용하여 직접적으로 포인터 주소를 가져올 수 있다.

라인 24, 25: release 함수는 포인터 주소를 리턴하면서 객체의 내부 값을 초기화 하는 것이다. 사용자가 직접 메모리를 해제해 주어야 한다. 실질적으로 어떤 경우 이런 함수가 필요한지는 잘 모르겠다. 별로 쓸일이 없을듯. 내부의 메모리를 실질적으로 해제까지 하는 것으로는 reset 함수를 사용하면 된다.



shared_ptr는 포인터를 다른 쉐어드 포인터에 넘겨줄 수 있다. 내부적으로 reference counter를 가지고 있어 모든 공유된 포인터 객체가 범위를 벗어나면 메모리를 해제하게 된다.

라인 36: reference counter를 확인할 수 있다.



레퍼런스는 포인터처럼 직접적으로 주소를 접근하지만 보통의 변수명 처럼 사용할 수 있다. 기존의 C++과 다르지 않은 사용법이지만 새로운 for문을 이용하여 객체 복사를 하지 않고 배열의 값을 변경할 수 있음을 테스트 해보았다.


배열과 반복문에 대한 부분이다. 아직까지는 C++의 기초적인 부분을 이어가고 있다.



brace 를 이용하여 동일하게 배열을 초기화 할 수 있다. 초기화시 배열의 갯수보다 적은 경우 자동으로 초기값이 입력된다. 많으면 컴파일타임에 에러가 발생한다.



배열의 사이즈를 알 수 있는 함수가 추가되었다. 이제 비 직관적인 sizeof 를 이용할 필요가 없어졌다!



만세이!!. for 문이 진화했다. 배열을 인식하여 루프를 돌 수 있게 되었다. 참고로 위에 145는 일일히 계산한 것은 아니다. 적당한 값을 입력하고 실행하여 테스트가 실행하면 계산값을 보여주며 실패하는데 이 숫자를 Test Explorer창에서 확인한 것이다.



이제 장점을 알다 못해 인이 배길 정도의 초기화이다. 자리 수 보다 적게 하면 적절한 초기값이 설절된다.



드디어 다차원 배열이 나오고 역시 초기화로 설명 시작이다. 테스트 코드를 보면 초기화의 기능을 알 수 있을 것이다.

라인 53 부터의 주석은 배열의 사이즈를 초기화를 통해서 지정할 수 있음을 보여준것이다.



STL을 이용한 배열이 나왔다. Vector와의 차이점은 한번 선언하고 나면 크기를 조절할 수 없다. STL array 전통적인 배열과 비교했을때 오버헤드가 없다고 한다.

line 67: array 도 초기화를 동일하게 할 수 있으며,

line 74: 멤버함수 fill을 통해 전체 배열을 동일한 값으로 설정할 수 있다.

line 77: 멤버함수 size를 배열의 크기를 알 수 있다.



배열은 ==, <, > 연사자를 이용해서 비교할 수 있다.

line 86: 두 배열의 사이즈가 같고, 각 요소의 값을 서로 같을 경우에 두 배열은 같다고 판단한다.

line 88: 두 배열의 각 요소를 일대일 비교하면서 서른 다른 값이 처음 나올때 그 두 요소값을 비교한다.

line 90: 전통적인 배열과 다르게 assign 연산자를 통해 배열의 값을 복사 할 수 있다.

line 93: 만약 호환성을 위해 전통적인 방식의 배열을 인자로 넘겨줘야 할 경우 멤버함수 data를 이용해서 얻을 수 있다.

분기문에 대한 설명이다. 이부분은 Modern C++도 재미있는 키워드를 추가한 것 이외에는 변경사항이 크게 없어 보인다. 단 이 추가된 부분은 매우 코드를 짜임새 있게 해 줄 것 같다.



if 문이 위와 같이 변수 생성을 포함할 수 있다. 그리고 그 변수의 생존 범위는 if 문 까지가 된다.




swtich 문도 동일한 기능을 추가하고 있다.

기본 데이타를 조작하는 방식에 대한 설명이다. Modern C++ 이전과 크게 달라진 것은 없어보이지만 몇가지 재미있는 기법과 키워드들이 추가되었다.



이전 장에서 배운 것 처럼 변수를 brace를 이용하여 초기화하고 bit masking 하는 법을 보여주고 있다.

라인 6 : 이진수로 초기화 하면서 구분자로 각각의 논리적인 영역을 표시하여 가독성을 높일 수 있다. 쓰면 쓸수록 괜찮은 기법이다. 이거 언제부터 가능해진거지? 책에서는 C11, 14, 17을 구분하면서 설명하지 않아 언제부터 가능해진 것인지 알기 어렵다.




이거는 사실 특별할 것 없는데 그동안 & 연산과 | 연산 이외에는 비트 연산을 해본적이 없어서 한번 테스트 해 보았다. 어떤 경우 이 연산이 필요한지는 아직도 모르겠다.



enum 값이 타입을 가질 수 있게 되었다. 더블어 enum도  class를 붙여줘야 한다. 내부적으로 어떤식으로 구현했는지 가늠해 볼 수 있는 부분이다.  enum 이 Type Safe 해 졌고, 열거형 변수를 사용하려면 :: 인 scope 지정자를 사용해야 한다.

이전의 enum 의 경우에는 하나의 네임스페이스 안해서는 열거형 변수명이 달라야만 했다. 하지만 class화 되면서 이젠 동일해서 컴파일에 문제가 발생하지 않는다. 또한 강제로 캐스팅 할 수 없고 명시적으로 static_cast 를 이용해야맘 한다.



이 코드는 어떤식으로 테스트 해야할 지 몰라 그냥 코딩만 해 두었다. 위 코드처럼 별명을 붙일 수 있다. 물론  이 기능은 typedef 과 동일할 거지만 = 기호로 인해 좀 더 가독성이 높아진것 같다.



전역변수의 경우 :: scope 연산자를 이용하여 좀더 가독성이 전역 변수임을 확인할 수 있다.

괄호를 이용하여 초기화 한다. 초기화에 별다를 게 뭐 있다고 이런 기능이 추가 됐나 하면서 내용을 읽어보았다.

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



라인 8을 보자. 괄호안에 값을 넣지 않으면 적절한 기본값으로 설정된다. 만약 괄호가 없었다면 어떤 쓰레기값이 있을지 모르겠다.

라인 15를 보자. 자리수를 그룹화 하여 표현할 수 있다. 물론 안해도 그만이지만 훨씬 더 가독성이 높아졌다. 물론 자리수를 3 자리나 4자리 아니 아무렇게나 해도 이의(?)를 제기하지는 않는단다.



괄호를 이용하면 변수가 허용하는 값 범위내에서는 초기화가 가능하다.




괄호를 이용해야만 16진수를 입력할 수 있는 것은 아니지만, 16진수를 입력할 수 있다. 8진수는 숫자 0, 2진수는 숫자 0 과 B를 분이면 된다.



sizeof  키워드는 글자 그대로 메모리에 차지하는 공간의 크기를 물어보는 것이다. 입력값이 실제 숫자이든, 자료형이던간에 그대로 할당되는 메모리 공간을 알려준다.



c++을 하다보면 땔레야 땔 수 없는 수치함수 들이다. 이참에 잘 이해하고 넘어가 보자.

라인 57 에서 절대값은 쉽다. 그저 음수를 양수로 바꿔주는 것이다. 그다음 ceil과 foor 인데, 우리말로 하면 올림과 자름정도 되겠다. 근데 그 올림과 자름이 0을 기준으로 하고 있다.

라인 65 부터는 exp, log, log10을 설명한다. 지수, 자연로그 등을 표현한다. 라인 71 부터는 root와 제곱이다. 지금 예를 들은 것은 딱 떨어지므로 EXPECT_EQ로 비교하였다. 실제로는 line 65처럼 비교해야 할 거로 생각된다.

라인 76은 정수와 가까운 쪽으로 처리된다. 즉 반올림이라고 할 수 있다. 숫자가 정확히 가운데를 가리킬경우 바깥쪽으로 정해진다.

그 외에 sin, cos, tan 값이 있고 인자는 항상 radian 값을 사용한다.

static_cast keyword를 이용한 명시적 변환히다. C++ 17에 국한된 연산자는 아니고 C++ 스타일의 cast 기법이다.

static_cast 는 컴파일 타임에 에러를 만든는 반면에 dynamic_cast는 런타임시 사용되며 상속관계가 있어야 사용할 수 있다.


최근 C++ 로 다시 업무를 해야할 일이 있을 것같아 다시 들여다 보고 있다. Modern C++은 기존에 내가 해오던 것에서 너무 많이 바껴서 새롭게 공부가 필요함을 느낀다. 아래 원서를 가지고 공부를 시작해야 겠다.



공부 방법은 늘상 하듯이 Unit Test를 만들어서 코드를 작성해보려고 한다. Visual Studio 2017에서는 C++ 기반으로 두가지 테스트 프로젝트를 제공한다. 이중 Google Test 를 이용하기로 하자.



책을 가볍게 흟어 보니 C++17 까지 설명한 책이지 C++17에서 새롭게 나온것 만을 설명하는 것은 아닌것 같다. Modern C++에 대해서 정식으로 공부해본 적 없는 나같은 old style C++ 프로그래머에게는 더 적절하겠다. 이후 정리는 Modern C++ 이라고 생각될 만한 것들만 정리하여 chapter 당 한 페이지씩 작성할 생각히고, 또한 정리한 source code를 github 에 올릴 생각이다. https://github.com/pronaman/DailtBookStudy.git



자 그럼 스타트!



Qt Creator 사용 시 기본이 되는 단축 키는 아래와 같다.

  • Ctrl+B - Build project
  • Ctrl+R - Run Project
  • Ctrl+Tab - Switch between open documents
  • Ctrl+K - Open Locator
  • Esc - Go back (hit several times and you are back in the editor)
  • F2 - Follow Symbol under cursor
  • F4 - Switch between header and source (only useful for c++ code)

더 자세한 단축키들을 보려는 아래 링크를 클릭하라.

http://doc.qt.io/qtcreator/creator-keyboard-shortcuts.html

 

또한 Menu의 Tools -> Option -> Environment 를 통해 확인할 수 있다.

 

 

 

It means open gl library need to be compiled. type the commnand below in a terminal.


sudo apt-get install libglu1-mesa-dev

+ Recent posts