12월 20, 2016

[EC++ 15] Provide access to raw resources in resource managing classes.


resource leak 방지는 well-designed system의 필수 요소 중 하나이다. 이런 목적으로 resource 관리에 RAII class가 사용되지만, 때로는 resource에 직접 접근할 수 있는 방법이 필요하다. 많은 API가 자신의 parameter로 resource를 받아 이에 직접적으로 접근하기 때문에, 이런 API를 활용하기 위해 RAII class는 자신이 관리하는 resource에 직접 접근할 수 있는 수단을 제공해야 한다. 이러한 접근 수단에는 explicit, implicit 두가지 방식이 있다.

  • explicit
    •  get()  method 제공
  • implicit
    • overloaded derefencing operator( -> ),  * ) 사용
    • overloaded type conversion operator 사용

단, implicit conversion은 편리한 반면 오류의 원인이 되기도 하므로 신중하게 사용해야 한다. 아래의 프로그래밍 의도는 Font 객체의 복사였지만, 실제로는 f1이 FontHandle로 형변환 된 후 이것이 복사된다. font handle은 원래 Font class를 통해 관리되고 접근 가능해야 하지만, 실행 결과 이를 관리하는 RAII 객체를 통하지 않고도 직접적으로 접근이 가능해졌다.



Conclusion

RAII class가 explicit conversion과 implicit conversion 등 어떤 access 방법을 제공할지는 해당 RAII class가 수행하는 작업과 RAII class가 사용되는 상황에 따라 달라진다. 가장 좋은 design 방법은 interface을 올바르게 사용하기 쉽고 잘못 사용하기는 어렵게 만드는 것이다.

RAII class 내부의 raw resource를 반환하는 메소드를 제공하는 것은 C++의 encapsulation 원칙을 어겨 C++의 원칙과 모순되는 것처럼 보인다. 그러나 RAII class의 목적은 raw resource의 관리이지 encapsulation이 아니다. 뿐만 아니라  std::shared_ptr 과 같은 RAII class는 true encapsulation으로 구현되어, underlying resource의 loose encapsulation과 결합하여 결과적으로 더 강한 encapsulation을 제공한다.



Summary

  • APIs often require access to raw resources, so each RAII class should offer a way to get at the resource it anages.
  • Access may be via explicit conversion or implicit conversion. In general, explicit conversion is safer, but implicit conversion is more convenient for clients.

Reference

  • Effective C++ by Scott Meyers

12월 13, 2016

[EC++ 14] Think carefully about copying behavior in resource-managing classes.


Synopsis

mutex를 사용하는 경우,  lock(..)  unlock(..) 을 매 번 잊지 말아야 한다. 이를 해결하기 위해 RAII(Resource Acquisition Is Initialization) class의 사용을 고려해 볼 수 있다.



RAII object의 copy behavior 정의

  • Prohibit copy
  • RAII 객체의 copy operation을 허용하지 않아야 하는 경우가 많이 있다. 예를 들어 underlying resource가  std::mutex 인 경우 copy operation은 의미가 없을 뿐 아니라, 잘못된 동작을 초래할 것이다.

  • Reference-count the underlying resource
  • 동일한 객체가 여러번 사용되는 경우, 마지막 사용이 끝난 시점에서 resource가 release 되어야 한다. 이런 경우 적합한 방식이 reference-counting 방식으로,  std::shared_ptr 와 같은 구현 예가 있다.

    만약 자신의 RAII class에 reference counting 방식을 도입하고 싶다면 referece counting을 직접 구현하지 않고,  std::shared_ptr 을 멤버 필드로 정의하여 같은 효과를 볼 수 있다. Synopsis의 Lock class를 이러한 방식으로 구현할 수 있는데, 이 경우 RAII class의 Reference-count가 0이 되어도 mutex가 destruct되어선 안된다. 이 구현은  std::shared_ptr 의 deleter를 지정하여 해결할 수 있다.

  • Copy the underlying resource
  • Resource-managing class를 사용하는 이유가 오직, heap 메모리의 자동 해제 뿐인 경우, 동일한 resource의 카피를 여러 개 보유할 수도 있다. 이런 경우 resource-managing class의 copy operation은 해당 객체의 underlying resource를 deep-copy 해야 한다.

  • Transfer ownership of the underlying resource
  • copy behavior가 해당 객체의 underlying resource의 ownership을 이양하는 경우를 생각해 볼 수 있다. 이러한 구현의 예로  std::unique_ptr 가 있다.



Summary

  • Copying an RAII object entails copying the resource it manages, so the copying behavior of the resource determines the copying behavior of the RAII object.
  • Common RAII class copying behaviors are disallowing copying and performing reference counting, but other behaviors are possible.

Reference

  • Effective C++ by Scott Meyers

12월 12, 2016

SQL DML(Data Manipulation Language) tag:


SELECT

  • Syntax
  • SELECT [table.]attrib1, [table.]attrib2, ...
    FROM table1, table2, ...
    [WHERE search_condition]
    [GROUP BY attrib1, attrib2, ...]
    [HAVING search_condition]
    [ORDER BY order_expression[ASC|DESC]];
  • 조건 연산자
    • 비교연산자 : =, =>, =<, >, <, IN 등

    • 논리연산자 : AND, OR, NOT 등

    • LIKE연산자 : *(%), ?(_), # 등의 기호를 사용해 문자열을 검색

    • BETWEEN : 특정 값의 사이에 있는 튜플을 검색

  • group funtions :  WHERE  SELECT 와 함께 사용되어 표시할 튜플을 선택하는 기준이 된다면,  HAVING  GROUP BY 와 함께 사용되어 그룹을 묶는 기준이 된다. 하나의 그룹을 모집합으로 사용되는 함수로, 일반적으로  HAVING  절과 함께 사용되어 그룹에 대한 조건을 지정한다.
    •  COUNT(attrib 그룹별 튜플의 수를 구한다
    •  MAX(attrib 그룹별 최대값을 구한다
    •  MIN(attrib 그룹별 최소값을 구한다
    •  SUM(attrib 그룹별 합계를 구한다
    •  AVG(attrib 그룹별 평균을 구한다

INSERT

  • Syntax
  • INSERT INTO table_name(attrib1, attrib2, ...)
    VALUES(value1, value2, ...);
  • 테이블의 모든 속성 값을 입력하는 경우에는 table_name 뒤의 속성명을 생략할 수 있다.
  •  SELECT  문을 사용하여 추출한 검색 결과를 삽입할 수도 있다.

DELETE

  • Syntax
  • DELETE FROM table_name
    WHERE condition;
  •  WHERE  절을 생략하는 경우 해당 테이블의 모든 튜플이 삭제된다.

UPDATE

  • Syntax
  • UPDATE table_name
    SET attrib1=value1, attrib2=value2, ...
    WHERE condition;

reference

12월 07, 2016

\b의 용도


 \b

 \b 는 back space를 의미하는 escape sequence로,  \n 과 같이 다음 출력의 위치를 바꿔주는 역할을 한다.  \n 는 다음 출력의 위치를 다음 줄로 바꿔주는데,  \b 는 다음 출력의 위치를 이전으로 한칸 이동(back space) 한다. 아래 예를 참고하자.

cout << "asdf";    // (1) asdf
cout << "1234";   // (2) asdf1234

(1)이 실행되면 콘솔에서 asdf가 출력된다. 출력을 계속하면 다음에 출력할 문자는 f 뒤부터 출력이 되는데, 이는 콘솔 상에서 마지막 출력의 다음 위치를 cursor가 가르키고 있다가 출력이 재개되면 cursor의 위치부터 출력을 계속하기 때문이다. 만약 되돌려진 커서의 위치에 기존 출력의 내용이 있다면 기존의 출력을 새로운 출력으로 덮어쓰게 된다.

// _ (underline)은 커서의 위치
cout << "asdf";    // (3) asdf_
cout << '\b';        // (4) asdf
cout << "1234";   // (5) asd1234_

이를 응용해 이미 출력된 내용을 지울 수도 있다.

// \b로 커서를 하나 되돌린 후 ' '(공백)을 출력해서 기존 출력을 지운 후, 다시 커서를 되돌림
cout << "asdf";    // (6) asdf_
cout << "\b \b";    // (7) asd_

reference

12월 03, 2016

Regular expression 정규 표현식


Regular expression이란?

정규표현식 혹은 정규식이라고도 부른다. Regular expression(regex or regexp)은 특정한 규칙을 가진 문자열을 표현하는데 사용하는 형식 언어이다. regex는 VIM, EMACS 등 많은 텍스트 편집기와 다양한 프로그래밍 언어에서 문자열의 검색과 치환을 위해 지원하고 있다.

regex 문법은 편집기 별로, 프로그래밍 언어별로 전체적으로는 비슷하지만 조금씩 다른 부분이 있기 때문에, 사용 시에는 이런 부분에 유의하며 사용해야 한다.


요소

  • abc...   letters
  • 123...   digits
  • \d   any digits
  • \D   any non-digit character
  • .   Any character
  • \.   period
  • [abc]   only a, b, or c
  • [^abc]   not a, b, nor c
  • [a-z]   chracters a to z
  • [0-9]   numbers 0 to 9
  • \w   any alphanumeric character
  • \W   any non-alphanumeric character
  • {m}   m repetitions
  • {m, n}   m to n repetitions
  • *   zero or more repetitions
  • +   one or more repetitions
  • ?   optional character
  • \s   any white space
  • \S   any non-white space
  • ^...$   starts and ends
  • (...)   capture group
  • (a(bc))   capture sub-group
  • (.*)   capture all
  • (abc|def)   matches abc or def


reference