12월, 2015의 게시물 표시

Visual Studio C++ Native Unit Test 짱

이미지
Visual Studio C++에서 Native Unit Test를 이용해보았다. 짱 좋다! method혹은 class 별로 Unit Test를 하는 습관을 길러야 겠다~ 기억할 것) 1. 테스트 프로젝트 (테스트할 프로젝트)가 export하는 class, function등에 대해서만 테스트 가능한 것 같다. (테스트 프로젝트의 구성형식을 .lib로 바꾸면  된다! 근데 안바꾸고도 할 수 있는 방법 없으려나?? ㅠㅠ .obj 을 다 인클루드하는 것 불편하고,,,another project와 함께 unite되서 build되는 그런 거 없나??? ㅠㅠ) 사진들------------------------- Unit Test 코드이다. testcase를 생성해서 test를 진행하면 된다. Assert::??? 를 이용해서 test성공여부를 결정할 수도 있다. 테스트를 하면 이렇게 테스트 성공 여부와 경과 시간이 뜬다. 테스트 출력 결과도 볼 수 있다~

Key가 있어야만 생성가능한 클래스만들기.

이미지
다음과 같은 상황을 가정하자.  특정 객체의 직접 생성을 막고 오직 factory function을 통해서만 객체를 생성할 수 있도록 하게 하려고 한다. 이럴 경우는 생성자를 private로 선언하고 클래스내의 factory function에서 private인 생성자를 호출하면 된다. 즉 위와 같이 작성하면 충분하다.  그런데 C++11에서 std::vector의 emplace_back, std::make_shared같이 내부적으로 arguments를 forwarding하여 생성자를 호출하는 함수를 사용할 경우에는 생성자가 private이기 때문에 위의 코드는 컴파일에러를 띄운다. 그렇다고 생성자를 단순히 public으로 놔버리면 초기의 목표에 모순이 된다.  첫번째 해결책으로 friend keyword를 떠올릴수있다. 그러나 이것은 일반적이고 쉬운 해결책은 아닌 것 같다. 일단 나의 경우 std::make_shared 에 friend선언을 하기 위해서 정보를 찾아봤는데 컴파일러버전마다 friend 선언이 달라진다고 한다. make_shared 외에 다른 것들에 대해서는 확인해보지 않았지만 일단 make_shared 만으로 제너럴하게 적용할 수 없기 때문에 좋은 방법은 아닌 것 같다. 그리고 일일히 friend 선언을 해줘야하므로 성가시고 귀찮다고 할 수 있다.  그래서 두번째 해결책을 소개하려고 한다. 이 것은 일종의 PrivateKey(HiddenKey) Class를 이용하는 방법이다.  코드를 그냥 보는 것이 이해가 빠를 것이다. A의 진짜 생성자(A())는 private로 감춰져있다. 하지만 A()로 리다이렉트되는 A(PrivateKey) 생성자가 public으로 공개되어있다. 하지만 PrivateKey가 있어야만 입장가능(?)하다. 하지만 PrivateKey는 private임으로 자기맘대로 가질수는 없다. 따라서 외부에서는 PrivateKey를 얻을 수...

[공지] 카톡 오픈채팅방을 만들었습니다!

카카오톡에 오픈채팅방이라는 기능이 생겼더라고요~ 익명으로 그룹 혹은 1:1채팅을 할 수 있데요 ㅎㅎ 그래서 저도 한번 만들어봤습니다~ 혹시 블로그 방문하시는분들 중에 포스팅한것에 대해 궁금한 점이 있거나 저랑 얘기나누시고 싶은 분은 이용하시면 좋을 것 같아요~~ https://open.kakao.com/o/sgjqqkf (1:1) https://open.kakao.com/o/gmr4pkf (단체)

Hack the PXE booting!

인터넷에서 우연찮게 아래의 기사를 보게 되었다. http://dailysecu.com/news_view.php?article_id=12221 기사의 내용은 PXE 부팅과정에서 이미지를 바꿔치기 하는 식으로 해킹이 가능하다는 것 이다. 마침 학교에서도 랩실 컴퓨터를 포멧할때 PXE를 활용하기 때문에 관심이 갔다. 그래서 어떤식으로 해킹이 이루어질지 생각해 보았다. 일단 PXE 부팅은 내부적으로 dhcp와 tftp 프로토콜을 이용한다. 일단 DHCP client가 먼저 동작해서 ip와 몇 가지 추가정보를 얻게 된다. 그리고 추가정보를 이용해서 tftp client가 tftp server에서 이미지 파일을 수신하고 부팅하게 된다. ( http://blog.pages.kr/156 ) 즉, 해킹을 하려면 dhcp spoofing을 이용해서 PXE booting을 시도하는 PC를 속이고, PC가 해커가 의도한 server로 부터 이미지를 수신받게 하면 되는 것이다. 아래링크는 DHCP spoofing과 방어기법 DHCP snoofing에 관련된 글이다. http://ryusstory.tistory.com/entry/DHCP-Snooping-Prevent-DHCP-Starvation-Attacks PXE spec 문서를 보면 자세한 내용을 알 수 있다. http://www.pix.net/software/pxeboot/archive/pxespec.pdf 위 문서의 13페이지를 보면 PXE Boot 과정에 대한 그림과 설명이 나와있다. DHCP Server와 통신후 Boot Server와 통신하는 것을 알 수 있다. 14페이지의 Step3를 보면 "The Boot Server list from the Boot Server field in the PXE tags from the DHCPOFFER." 란 부분을 볼 수 있다. 즉 이를 통해 hacker는 DHCP가 unauthorized 하다는 점을 이용해서 실제 dhcp서버보다 먼...

new보단 make_shared를 사용하자. (but not always)

C++11에서는 총 3가지의 smart pointer를 지원한다. (shared_ptr, unique_ptr, weak_ptr) 이 때 make_shared를 사용할 때는 std::shared_ptr<T> ptr(new T(a,b,c)) 보다는 std::shared_ptr<T> ptr = std::make_shared(a,b,c); 를 사용하는 것이 좋다. 그 이유는 전자의 경우에는 actual object를 생성하고, control block이 따로 생성되는데 후자의 경우에는 내부적으로 actual object와 control block을 함께 생성하기 때문이다. 따라서 후자가 좀더 효율적이라고 할 수 있다. new의 호출 횟수만 봐도 전자는 2번, 후자는 1번이다. 그리고 후자의 경우가 당연히 locality와 memory fragmentation의 측면에서 더 좋다. 그러나 무조건 좋은 것만은 아니다. 전자의 경우에는 reference count가 0이 되면 actual object가 소멸되고, weak reference count 마저 0이 됐을 때 control block이 소멸되지만, 후자의 경우에는 reference count와 weak reference count가 모두 0이 됐을 때 비로소 actual object와 control block이 함께 소멸되게 된다. http://itability.tistory.com/37 를 보면 장단점에 대해서 좀 더 알 수 있을 것이다. (이 블로그의 modern c++카테고리에 C++팁이 잘 정리되어있는 것 같다. ) http://egloos.zum.com/hellpme/v/1543080 를 보면 어떤 사람이 실제로 성능을 비교한 결과가 있다. 만약 최적화를 하지않았을 때 오히려 new보다 make_shared가 느린 이유는 make_shared의 경우에는 move constructor가 추가로 호출되기 때문인 것 같다. (~~ ptr = ~~ 이니까) ...

C++ 2D subscript overloading using typecasting.

이미지
C++에서 연산자오버로딩을 이용하면 코드의 가독성을 좋게 만들 수 있고, 좀 더 편하게 객체를 사용할 수 있게 된다. 예를 들어 Array 클래스가 있을때, Array array; .... n = array.get(10); // 1 n = array[10]; // 2 두 가지 방법중 subscript overloading을 이용한 2번 방법이 보기 편하고 직관적일 것이다. 만약 2D subscript overloading, 즉 [][] 연산자를 overloading하려면 어떻게 해야할까? 실제로 [][] 연산자는 존재하지 않고, [] 가 2번 연산된 것으로 처리된다. 따라서 이를 수행하려면 http://stackoverflow.com/questions/6969881/operator-overload 와 같이 Proxy Class를 이용해야한다. Proxy객체를 이용하면 생성하고 초기화하고 소멸하는 등에 대한 추가적인 overload가 든다. 오늘 그래서 내가 생각해낸 방식이 Imaginal Proxy Class 라는 방법이다. (이름은 내가 지었다..) Proxy Class는 사용하되 객체는 생성하지말고, type casting을 이용해 Proxy Class의 subscript operator만 사용하게끔하는 것이다. 아래가 그 예이다. 음?? 왜 이거 짤때 *reinterpret_cast<PixelArray*>~~ 이런식으로 했지?? 포인터쓸 필요없이, 그냥 레퍼런스 이용해서 reinterpret<PixelArray&>(data[idx * width]) 이런식으로 하면 됩니다 ㅋㅋㅋㅋ 위에서 PngImage가 우리가 2D subscript operator overloading을 하려는 대상이고, PixelArray가 그 것을 위한 Proxy Class이다. PngImage::data에 pixel정보들이 차례로 나열되어 있다. Image와 PixelArray의 operator[]를...