본문 바로가기

Programming

[C++11] static_assert를 통한 컴파일 타임 검증 static_assert는 컴파일 타임에 소프트웨어 assertion을 위해서 추가된 문법입니다. 만약 작성된 constant-expression이 false(거짓)일 경우에 컴파일러는 메시지를 출력하고 C2338 에러를 출력합니다. 만약 true라면 아무런 영향도 발생하지 않습니다. 이미 C++에는 #error 전처리기 지시자와 assert 매크로를 통해서 assertion 처리가 가능합니다. 다만 C++의 assert는 런타임에 비교를 수행하기 때문에 성능의 하락을 가져올 수 있는 단점이 있습니다. 컴파일 타임에 해당하는 문제를 더 빨리 찾아내는 것이 모든 면에서 더 낫다고 할 수 있습니다. #error의 경우는 컴파일 타임에 처리가 가능합니다. 다만 템플릿이 구체화되기 전에 수행되버리기 때문에 템플.. 더보기
MFC, API 프로그래밍에서 유니코드 처리하기 요즘은 거의 대부분 유니코드를 적용해서 프로젝트를 진행할 것으로 보입니다.멀티바이트 문자열을 받는 대부분의 Win32 API 함수들은 유니코드로 바꿔서 다시 유니코드 함수를 호출해줍니다.그러니 바로 유니코드 형식을 사용하는 편이 더 효율적이라고 할 수 있습니다.일반적으로 API 함수가 오류가 나면 함수명에 A나 W가 붙죠.MessageBox라는 메시지 박스를 띄우는 게 오류시 MessageBoxA / MessageBoxW로 표기가 됩니다.여기서 A냐 W냐가 멀티바이트 코드 함수, 유니코드 함수로 구분이 됩니다.멀티바이트 코드인가 유니코드 프로젝트인가를 확인해서 해당하는 API를 호출하는 것은 #define 전처리기를 통해 가능합니다.#define UNICODE로 정의되어 있으면 자동으로 유니코드 함수를 .. 더보기
Windows 메시지의 구조와 처리 Windows 프로그래밍은 메시지를 기반으로 하는 프로그램을 작성합니다.Windows는 메시지를 끊임없이 발생시키고 이 메시지를 처리하게 만들어 주는 것입니다.Win32 프로그래밍을 하다보면 메시지 루프라는 용어가 쓰입니다.이 부분이 메시지를 받아서 메시지를 처리하는 부분이 됩니다.WinMain에는 다음과 같은 코드가 들어가 있습니다. MSG msg; HACCEL hAccelTable; // Initialize global strings LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_WIN32PROJECT1, szWindowClass, MAX_LOADSTRING); MyRegisterClass.. 더보기
wcout, wprintf 등에서 한글 출력 안될 때 해결법 유니코드 프로젝트에서 wcout이나 wprintf를 사용했을 때 한글이 출력이 안되는 문제가 생길 때가 있습니다.이럴 때 문제를 해결하기 위해서 setlocale() 함수를 사용하면 됩니다.main 함수 등에서 다음과 같이 호출하면 됩니다. setlocale(LC_ALL, ""); 이렇게 하면 시스템의 로케일을 따라가기 때문에 한글 윈도우에서 정상적으로 한글이 출력됩니다.""를 "korean"으로 변경하면 한글로 특정해서 호출할 수도 있습니다.wcout에서 한글이 정상적으로 출력되지 않을 때 다음과 같은 방법으로 처리할 수도 있습니다. std::wcout.imbue(std::locale("")); 이후에 wcout을 호출하게 되면 정상적으로 한글이 출력되는 것을 알 수 있습니다. 더보기
얕은 복사(Shallow Copy) vs 깊은 복사(Deep Copy) 객체를 생성하고 대입하게 되면 복사 생성자가 호출되어 값을 복사하게 됩니다.클래스의 복사 생성자는 별도로 정의하지 않아도 생성되는 특수한 함수입니다.이렇게 기본적으로 내부에 생성되는 복사 생성자는 int 등의 타입에는 정상적으로 동작합니다.하지만 다음과 같이 포인터 등을 사용할 경우에는 문제가 발생할 소지가 있습니다. #include #include class Person { public: Person(int nAge, char* pName) { m_Age = nAge; int nLen = strlen(pName) + 1; m_Name = new char[nLen]; strncpy(m_Name, pName, nLen); } ~Person() { if (nullptr != m_Name) { delete[].. 더보기
[C++11] default와 delete 키워드 C++의 클래스는 기본적으로 다음의 특수한 멤버 함수를 생성합니다.기본 생성자 복사 생성자 복사 대입 연산자 소멸자클래스를 생성하고 아무것도 하지 않아도 위의 4개는 기본적으로 생성됩니다.이것으로 클래스는 기본적으로 아무것도 추가하지 않아도 생성, 복사, 소멸이 가능해집니다.C++11에서는 기본적으로 생성되는 특수 멤버 함수에 무브 생성자와 무브 대입 연산자가 추가되었습니다.이 특수한 멤버 함수들을 명시적으로 선언하면 다음과 같은 규칙이 발생합니다.1. 어떤 생성자(복사 생성자 포함)가 명시적으로 선언된 경우 기본 생성자는 자동적으로 생성되지 않는다.2. 가상 소멸자가 명시적으로 선언된 경우 기본 소멸자가 자동적으로 생성되지 않는다.3. 무브 생성자나 무브 대입 연산자가 명시적으로 선언된 경우 1) 복사.. 더보기
[C++11] 새로운 스마트 포인터 unique_ptr(auto_ptr의 대체) C++11에서 auto_ptr이 사라지고 unique_ptr이 새로 추가되었습니다.auto_ptr의 문제점에 대해서는 아래의 글을 확인하시면 됩니다.2014/12/08 - [Programming/C&C++] - 스마트하지 못한 스마트한 포인터 auto_ptrauto_ptr을 대체하는 unique_ptr에 대해서 알아보도록 하겠습니다.unique_ptr은 auto_ptr과 거의 유사한 멤버를 가지고 있습니다.동적 할당된 포인터를 받아서 해당 포인터를 핸들링하고 자동으로 메모리를 해제하는 역할까지 동일합니다.* 연산자나 -> 연산자도 auto_ptr과 동일하게 지원합니다.unique_ptr을 생성하는 코드를 보도록 하겠습니다. #include #include #include struct TestStuff {.. 더보기
MFC 클래스 계층도(hierarchy chart) MFC 클래스 계층도는 Visual Studio 2008 Feature Pack과 함께 더욱 방대해졌습니다.MFC의 대부분의 클래스는 CObject를 상속받습니다.CObject를 상속받지 않는 클래스도 일부 존재합니다.MFC 클래스 계층도는 다음과 같습니다.윈도우 컨트롤들은 CWnd를 상속받아서 작성되는 클래스로 되어 있습니다. 더보기