2015년 4월 23일 목요일

[C++] Member initializer



생성자는 초기화를 하는 것이 기본적이지만, 위 코드는 생성과 동시에 초기화한 것이 아니고, 대입한 것이다. 
Member initializer : 멤버 변수의 초기화를 위해 사용되는 문법 
생성자 옆에 콜론(:) 을 사용하여 초기화 한다.




[C++] extern "C"


math.h math.c test.cpp
extern "C" {} 는 C언어로 만들어진 library가 C++ 컴파일러에서 동작되게끔 하려는 것이다.
C++ 컴파일러가 C로 만든 Library 를 컴파일 타임에 name mangling 하지 않도록 'extern "C" {}'를 선언함으로써 방지할 수 있다.
하지만 C컴파일러는 extern "C" 키워드를 인식하지 못하므로 C++에서만 동작하도록
__cplusplus 키워드를 추가하여 C++컴파일러에서만 동작하도록 해야 한다.

만약 extern "C" {} 없이는 complier 는 아래와 같이 에러를 출력한다.
>  math.c
>  test.cpp
>test.obj : error LNK2019: "int __cdecl square(int)" (?square@@YAHH@Z) 외부 기호(참조 위치: _main 함수)에서 확인하지 못했습니다.
>C:\Users\Administrator\Desktop\extern_test\Debug\extern_test.exe : fatal error LNK1120: 1개의 확인할 수 없는 외부 참조입니다.

math.c, test.cpp 는 각각 c, c++ 컴파일러에 의해 컴파일 된다.
하지만 test.cpp 가 컴파일 되기 전에 전처리기에 의해서 math.h는 치환될 것이고
#include "math.h" -> int square(int x) 
그리고 컴파일 타임에 name magling 되어 어셈블리 코드에서 square 의 name이 변경되어 링킹 시점에 에러가 나게 된다.

그래서 math.h 에서 이것은 C 컴파일러로 컴파일되어야 하므로
extern "C" 키워드를 사용해서 c++ 컴파일러에 의해서 name mangling 이 되지 않도록 해야 한다.

하지만 extern "C" 에서 "C"는 c컴파일러가 받아들이지 못하는 문법이다.
그래서 c++ 표준에서는 __cplusplus 매크로를 정의한다.
c++ 컴파일러에서 컴파일 될경우 __cplusplus 매크로를 판단하여 빌드를 결정하면 된다.
#ifdef, #else, #endif

모든 functions 에 extern "C" 를 작성하는 불편을 줄이기 위해서
external linkquize block 을 사용하여 효율적으로 처리할 수 있다.

extern "C" {
...
}

[C++] meta programing

재귀 호출에 관해 template meta programming 을 적용한 예제를 살펴보자. #include using namespace std; int fact(int n){ if(n factorial 연산을 하는 일반적인 재귀 호출 함...