6월 04, 2017
6월 24, 2016
reference type의 null 할당을 위한 static member null object(NullObject) 정의
Synopsis
C++에서 pointer 사용을 줄이기 위해서 가급적 reference type을 사용하려 하는데, pointer가 null 값을 가질 수 있는데 반해 reference type은 null을 가질 수 없어 reference type을 멤버로 갖는 객체 초기화 등에 불편. 이를 해결하기 위해 클래스에 static member로 해당 클래스 타입의 NullObject를 정의하고, 해당 클래스의 reference type이 null 값을 가져야 할 때 이 static null object를 줌.
Example
- case 1: NullObject가 정상적으로 작동함.
- case 2: NullObject의 주소를 확인 -> 주소 비교를 통해 현재 object가 NullObject인지 아닌지 체크 가능.
- case 3: NullObject inheritancy test 1
- case 4: NullObject inheritancy test 2
실제 이런 implementation을 사용 시에는 객체가 관련된 프로세스 과정에서 현재 객체가 NullObject인지 아닌지 객체 처리 전에 체크할 수 있는 nullCheck()나 isValid() 등의 멤버 함수를 추가로 정의.
더 생각해볼 점
- NullObject는 const 선언이 되어야할까?
- NullObject가 move 또는 copy 된다면?
- NullObject에 singleton 패턴을 응용할 수 있지 않을까?
NullObject는 변경이 되선 안되므로 const 선언이 되는게 맞지만, 이 경우 이 NullObject를 받는 다른 reference type들도 모두 const 선언이 되어야하는 문제가 있음. 원래 NullObject는 reference type을 단순히 '임시로 초기화' 하기 위한 임시값인데, NullObject 때문에 reference type이 const reference type으로 선언이 되면 이후 이 reference type을 통해 가르킬 다른 객체들의 내부 값 수정이 불가능해짐.
이 경우도 문제가 생길 것 같은데.. move constructor나 copy constructor에 NullObject의 move나 copy를 막기 위한 NullObject 검사 과정이 필요함.
Reference
- -
5월 09, 2016
MSSQL ODBC vs OLEDB vs ADO
- ODBC
- OLEDB
- ADO
- ADO.NET
- 기타
ODBC (Open DataBase Connector)
- 1992년 소개
- SQL data source만 처리 가능
- base는 C++ (MFC database classes가 ODBC를 베이스로 하고 있음), Java(JDBC)
- platform independent, 윈도우 리눅스 상관 없이 사용가능.
OLEDB (Object Linking and Embedding DataBase
- 1996년 소개
- ODBC가 SQL data만 처리 가능한데 반해, non-SQL data source도 처리 가능
- C++, Java
- COM을 이용하기 때문에 윈도우 종속적.
- SQL data source 접근할 때는 ODBC를 통해 접근한다는 설명도 있고 ODBC 없이 직접 접근할 수 있다는 설명도 있음. (확인 필요).
- OLE DB 는 deprecated 됨.
Microsoft is Aligning with ODBC for Native Relational Data Access |blog.msdn.microsoft
ADO (ActiveX Data Object)
- 1996년 소개
- OLEDB의 high level interface. 다양한 언어에서 사용 가능.
- C++, C#, Java, VB, Script 언어(웹 어플리케이션)
- DB 접근 시 OLEDB를 거쳐가기 때문에 윈도우 종속적.
- 요즘 잘 안쓰인다는 설명이 있음. 확인 필요. //rev
ADO.NET
- 2002년 소개
- OLE DB 및 ODBC를 통해 노출되는 데이터 소스, SQL Server 및 XML과 같은 데이터 소스에 대한 일관성 있는 액세스를 제공
- C#, Java, VB, Script 언어(웹 어플리케이션)
- DB 접근 시 ADO를 거쳐가기 때문에 윈도우 종속적.
- 요즘 잘 안쓰인다는 설명이 있음. 확인 필요. //rev
기타
- DAO
- RDO
ODBC와 유사하나 ODBC가 다양한 데이터베이스에 접근할 수 있는데 반해 DAO는 local machine에 존재하는 데이터베이스에 빠르게 접근하기 위한 목적으로 개발됨.
서버에 기반을 둔 데이터베이스를 위한 기술로 RDS가 뒤를 이은 후 현재는 잘 사용되지 않음.
그림1

그림2 (MSDN)

reference
5월 06, 2016
git cherry-pick 사용법
Given one or more existing commits, apply the change each one introduces, recording a new commit for each. This requires your working tree to be clean (no modifications from the HEAD commit).
다른 branch로부터 특정 commit을 가져와서 추가. 추가한 commit으로 새로운 commit이 생기며(hash값이 다름) 해당 commit에서 이루어진 변경 사항만 적용됨.
더 연구할 점
- reference에 따르면 cherry-pick하는 commit 만의 변경 사항을 가져올 것 같은데, 실제로는 conflict("both modified: 파일명") 가 발생하며 현재 branch와 cherry-picking branch의 공통 부모로부터 cherry-picking commit까지 모든 commit을 가져옴 (변경 사항을 누적시켜 모두 가져옴).
- 새로운 파일을 생성하고 만든 첫 commit을 cherry-pick하는 경우에는 merge conflict 없이 cherry-picking 됨
- 만약 새로운 파일을 생성하고 해당 파일을 수정하며 여러번 commit하고 이중 하나의 commit만 cherry-picking 하는 경우 conflict("deleted by us: 파일명") 발생하며 현재 branch와 cherry-picking branch의 공통 부모로부터 cherry-picking commit까지 모든 commit을 가져옴 (변경 사항을 누적시켜 모두 가져옴).
reference
- Cherry-Picking specific commits from another branch
- git-cherry-pick |git-scm.com
- How to git-cherry-pick only changes to certain files? |stackoverflow.com
- git - How to cherry pick only changes for only one file, not the whole commit |stackoverflow.com
- Why does git cherry-pick not continue? |stackoverflow.com
- Git: cherry pick inserts changes from other commits |stackoverflow.com
- Why cherry-pick pick change more than one commit? |stackoverflow.com
3월 22, 2016
move semantic 구현
move constructor와 move assignment operator를 정의
move constructor를 정의
- move constructor
- move assignment operator
move constructor의 경우moved-to-obj의 리소스를 해제하고 그 자리에 move-from-obj의 리소스를 배정. move-from-obj의 리소스 참조를 끊어줌.(ex. pointer를 nullptr로 변경)
move-to-obj와 move-from-obj가 동일한 객체인지 검사하고 동일하지 않은 객체일 경우 이동 작업을 진행.
코드의 간략화
move assignment operator를 이용해 move constructor의 중복 코드를 제거할 수 있음.
기타
- move constructor의 move-from-obj destruct
일반적으로, move constructor에서 move-from-obj를 destruct 해주지는 않음. 그러나 move constructor가 불린 후 꼭 move destructor가 뒤따라 불리는데, 이건 move constructor가 move-from-obj를 destruct해서가 아니라 함수에서 임시로 생성됐던 객체가 move constructor가 불린 후 life time이 끝나 해제가 된 것. move constructor에서 move-from-obj의 destruct해야할 어떤 책임도 없음.
rvalue를 param.로 받는 함수를 overloading.
perfect forwarding?
references
- 이동 생성자 및 이동 할당 연산자(C++) |MSDN
- Move constructor not calling destructor? |stackoverflow
- ---
- c++ move semantic |google search
- why is the destructor call after the std::move necessary? |stackoverflow
- c++11 Return value optimization or move? |stackoverflow
- Move semantics and rvalue references in C++11
- Move Constructor
- C++11 Tutorial: Introducing the Move Constructor and the Move Assignment Operator
1월 29, 2016
ch15. Input/Output using stream classes
0. Overview
- C++11부터 string stream과 file stream이 rvalue와 move semantic을 지원.
- 1. Background of I/O streams
- 2. Fundamental stream classes and objects
- 3. Standard Stream Operators << and >>
- 4. State of Streams
- 5. Standard Input/Output Functions
- 6. Manipulators
- 7. Formatting
1. Background of I/O streams
- stream objects
- stream classes
- global stream objects
- cin
- cout
- cerr
- clog
- stream operators
- manipulators
- a simple example
output : stream으로 흘러들어오는 데이터
input : stream에서 흘러나가는 데이터
class istream : 데이터를 읽는데 사용되는 input stream
class ostream : 데이터를 쓰는데 사용되는 output stream
stream을 조작하기 위해 사용되는 특수한 object. input을 읽어들이는 방식이나 output이 출력되는 방식을 바꾸는 유일한 방법임.
2. Fundamental stream classes and objects
- Classes and class hierarchy
- Global stream objects
- cin - istream
- cout - ostream
- cerr - ostream
- clog - ostream
- Header files
//rev header file including structure
IOStream library는 철저히 각자의 책임을 분리하는 방향으로 설계됨. basic_ios를
상속받는 클래스들은 오직 formatting data만을 처리함. characters의 읽기와 쓰기는
basic_ios의 subobjects인 stream buffers에 의해 수행됨.
application programmer는 <iosfwd>를 include하는 것으로 충분하며,
input, output functions을 사용하기 위해 필요에 따락 각각
<istream>과 <ostream>을 include한다.
일반적으로 헤더 파일에는 꼭 필요한 파일만 include 한다. 특히 헤더파일에는 <iosfwd>만
include하고, 이에 대응되는 implementation 파일에 헤더 파일을 include해서 완전한 정의를
하도록 한다.
3. Standard Stream Operators << and >>
bit shift 연산자인 <<와 >>를 overloading 하여 입출력 연산자로 사용. void와 nullptr_t을 제외한 거의 모든 data type에 대해 overloading 되어있음.
- Output Operator <<
- Input Overator >>
- Input/Output Of Special Types
- Numeric type
- Type bool
- Types char and wchar_t
- Type char *
- Type void * void * 를 사용 시 pointer 출력(memory address 출력)도 가능.
- Stream Buffers
- User-Defined Types
- Monetary and Time Values
C++11에서 같은 stream object를 concurrent output에 사용하는 것이 가능하지만 이 경우 출력이 서로 섞일 수 있음.
두번째 param.는 non const value여야 함.
C++11에서 같은 stream object를 concurrent input에 사용하는 것이 가능하지만 이 경우 입력이 서로 섞일 수 있음.
input 읽을 때 적어도 한자리 숫자로 시작해야함. 그렇지 않으면 value는 0이 되고 failbit이 set 됨.
false는 0으로, true는 1로 converting.
leading whitespace is skipped by default. whitespace까지 읽고 싶을 때는 flag _skipws_를 clear하거나 member function get()을 사용.
read wordwisely. leading whitespace is skipped by default. 다음 whitespace 나 end-of-file을 만날 때까지 읽음. flag _skipws_를 통해 leading whitespace를 skip할지 정할 수 있음. 만약 읽을 문자의 숫자를 지정하고 싶다면 setw(..) 를 사용.
char buffer[81]; std::cin >> std::setw(81) >> buffer;char * 를 사용하기보다 std::string 을 사용할 것을 권장. 이 경우 getline()을 통해 line 단위로 입력이 가능.
char * cstring = "hello"; std::cout << static_cast<void *>(cstring) << std::endl; // cstring의 주소가 출력됨
C++ I/O/ streams를 이용해서 파일을 복사하는 가장 빠른 방법. 15.14.3 참조.
4. State of Streams
Stream에는 I/O가 성공했는지 실패했는지, (실패한 경우) 실패한 이유 등이 기록된 state가 있음.
- Constants for the State of Streams
- goodbit
- eofbit
- failbit
- badbit
- Member Functions Accessing the State of Streams
- Stream State and Boolean Conditions
- Stream State and Exceptions
flags는 class basic_ios 에 포함되어있기 때문에 class basic_istream 또는 class basic_ostream 의 모든 객체에 존재한다. 그러나 stream buffer는 아무런 state flag를 가지지 않는데, 이는 하나의 stream buffer 가 여러개의 stream 객체에서 사용될 수 있기 때문.
error bits는 언제나 명시적으로 clear 해줘야 함.
operator >> 의 default 설정은 leading whitespace를 skip함. 이런 whitespace skip을 막고 싶다면 stream member function의 put()과 get() 을 사용할 수 있으며, 이보다 나은 방법으로 istreambuf_iterator를 이용해 I/O 필터를 구현할 수도 있음.
if ( !(std::cin >> x)) { // !뒤의 괄호 위치에 주의
// the read failed
...
}
backward compatibility를 위해 stream는 exception을 던지지 않는 것이 default로 설정되있지만, 모든 flag에 대해 flag가 set 되었을 때 exception을 던지게 설정할 수 있음.
exception은 보다 더 unexpectied situation에서 사용되어야 함. input/output 과정에서의 format error와 같은 error는 정상으로 간주되며, exception 처리 보다는 state flag를 통한 처리 방법이 더 좋은 방법임.
5. Standard Input/Output Functions
| formatted operator | unformatted operator |
|---|---|
| << / >> | get(..), getline(..), read(..) put(..), write(..) |
| skips whitespaces | never skips leading whitespaces |
- Member functions for input
- get(c, num)
- get(c, num, t)
- getline(str, num)
- getline(str, num, t)
- read(str, num)
- readwome(str, num)
- etc..
- Example Uses
- sentry objects
그러나 C-strings를 읽을 때는 위의 함수들보다 operator >>를 사용하는 것이 더 안전함.
character나 string을 읽을 때 istream member function을 사용하는 것보다 stream buffer를 통해 바로 접근하는 것이 더 유리할 때가 많은데, 이는 stream buffer member function은 input 과정에서 (istream class와 달리) sentry object를 생성하지 않아 construction overhead가 없기 때문.
I/O stream operators 와 functions에서 I/O는 I/O preprocessing, 실제 I/O 작업, I/O postprocessing의 3단계에 걸쳐 수행됨. sentry class는 이를 위한 보조 클래스의 일종으로, stream과 관련된 여러 state에 관한 정보를 담고 있음. 만약 I/O operator를 stream buffer에 바로 적용하기 위해선 sentry object를 먼저 생성해줘야 함.
Manipuators
Manipulator for streams는 standard I/O operators에 적용되어 stream의 특성을 바꿔주는 object를 말함. arguments를 가지는 standard manipulators는 헤더파일 <iomanip>에 정의되어 있으며, 이를 사용하기 위해선 이 헤더 파일을 include해야함.
- Overview of All Manipulators
- endl
- ends
- flush
- skipws
- noskipws
- setw
- setfill
- boolalpha
- showpos
- dec
- hex
- ...
- How Manipulators Work
- User-Defined Manipulatrs
manipulator가 어떻게 작동할지는 구현하기에 따라서 달라지며, 구현 과정에 있어서 표준적인 방법은 존재하지 않음.
Formatting
- Format Flags
- Input/Output Format of Boolean Values
- Field width, Fill Character, and Adjustment
- Positive Sign and Uppercase Letters
- Numeric Base
- Foating-Point Notation
- General Formatting Definitions
출처
the c++ standard library a tutorial and reference by Nicolai M. Josuttis1월 04, 2016
git branch 조작법
Local branch
- local branch 이름 수정
- remote branch를 local branch로 가져온 후 track
- 모든 local branch들을 한번에 remote repository에 업로드
- git checkout -t remote_branch_path
git branch -m old_branch new_branch
git checkout -b new_local_branch remote_branch_path
주의! remote repository가 지저분해질 수 있음
git push --all  git push --tags
git push 로는 branch만 올라갈 뿐 tag는 올라가지 않음. 따라서 tag는 따로 올려줘야 함.
remote_branch_path를 tracking 하는 local branch를 만들고 checkout. 이 방법으로 새 local branch를 만들 시 branch의 이름은 remote branch의 이름과 동일하게 만들어짐.
Remote branch
- remote branch 삭제
git push origin :old_branch or git push origin --delete romote_branch // remote
branch 삭제 git fetch --all --prune // 각 local machine에서 실행. to get rid of obsolete tracking branch 제거 remote branch를
삭제해도 다른 local machine들에서는 여전히 삭제된 remote branch를 tracking 하고 있는 상태. obsolete tracking을 막기 위해 다른 local machine에서
실행
12월 30, 2015
12월 27, 2015
12월 25, 2015
Git 유용한 명령어 모음
branch 조작
기타
- log: commit 히스토리를 보여줌
- --graph: 히스토리를 그래프로 보여줌
- --pretty: 히스토리 옵션에 맞춰 깔끔하게 출력함.
12월 16, 2015
C++11 lambda expression
- Syntex of lambda
[caps] {
function_contents;
};
또는
[caps] (params) (mutable) (throwSpec) (->retType) {
function_contents;
};
- caps: captures. 외부의 변수 값을 람다 내부에서 사용할 수 있게 함
- params: 람다는 일반 함수와 마찬가지로 파라미터 값을 받을 수 있는데, 이와 같이 파라미터 값을 람다 내부로 건네주는데 사용
- mutable : 람다에 mutable 선언시 value 로 전달된 captures를 람다 내부에서 수정할 수 있으며 수정된 값은 람다 내부에서 유지. (value로 전달 됐으므로 람다 밖에서는 수정된 값이 적용되지 않음)
- throwSpec
- retType: 람다는 일반함수와 마찬가지로 값을 리턴할 수 있는데, 이 리턴값의 type을 지정하는데 사용
- function_contents: 람다가 수행하는 내용
- ex)
int x = y = 1;
auto l = [=x, &y] -> bool {
if ( ++x == ++y )
return true;
else
return false;
};
// true 리턴, x는 1, y는 2 값으로 변경.
- lambda의 장점
- lambda의 한계