More C++ Idioms-4. Attach by Initialization

old_dorim·2022년 7월 9일
1

More C++ Idioms

목록 보기
4/4

More C++ Idioms

https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms

Idioms라는 용어가 생소하다. 한국어로 하면 관용구인데, 개발 용어로는 그냥 관용구라고 생각하면 안될 것 같아서 서문을 살짝 읽어봤다.

Idiom라는 것은 C++를 사용하여 프로그래밍하거나 설계할 때 자주 사용하게 되는, 재사용 가능한 패턴이나 팁이다. 특정 상황에서 쓰이는, 특정 상황에 대처하기 위한 일반적인 관행이라는 뜻이다.

이 목록은 이런 관용구들을 모아둔 리스트이다. 이 관용구들을 이해함으로써 다른 사람의 코드가 왜 그렇게 짜였는지 읽기 쉬워지고, 언어가 어떤 특성을 가져서 어떻게 짜면 좋은지 등등을 이해할 수가 있다.

이 목록들은 각각 Idiom의 Intent, Also Known As(Alias), Motivation, Solution and Sample Code, Known Uses, Related Idioms, References를 설명한다. 양식이 그렇게 되어있다. 나도 맞춰서 정리하겠다.

동아리 세미나 과제인데, 빨갛게 안 만들어진 페이지빼고 공부한다.

4. Attach by Initialization(Static-object-with-constructor)

Intent 목적

프로그램 실행 이전에 프레임 워크에 유저가 정의한 객체를 붙인다. 동기를 읽는게 더 이해가 된다.

Motivation 동기

GUI(ex.Microsoft MFC)나 object request brokers같은 특정 프레임 워크는 자기만의 이벤트 루프를 가지고 전체 어플리케이션을 컨트롤한다.

이런 경우 어플리케이션 프로그래머는 메인 함수를 쓰지 못할 수 있다. MFC의 메인 함수인 AfxWinMain처럼 메인 함수 자체가 깊게 숨겨져 있는 경우도 있다. 이렇게 메인함수에 접근 못하는 경우 이벤트 루프가 시작되기 전에 초기화 코드를 쓸 수가 없게 된다. The attach-by-initialization idiom으로 프레임워크를 컨트롤하는 루프가 시작되기 전에 특정 코드를 실행할 수 있게 한다.

Solution and Sample Code 솔루션과 예제코드

C++에서, 전역 namespace에 있는 전역 오브젝트와 정적 오브젝트는 main이 시작되기 전에 초기화 된다. static storage duration(메모리에 데이터를 저장하고 있는 시간. static의 경우 프로그램이 실행되는 동안 계속 메모리에 저장되어 있다)라는 특성을 가지는 오브젝트들이다. 이런 오브젝트들을 써서 시스템 프로그래머가 메인 함수에 접근할 수 없을 때 시스템에 메인 함수 이전에 실행 되는 객체를 붙일 수가 있다. 아래가 Microsoft Foundation Classes(MFC)에서의 예시이다.

///// File = Hello.h
class HelloApp: public CWinApp
{
public:
  virtual BOOL InitInstance ();
};
///// File = Hello.cpp

#include <afxwin.h>
#include "Hello.h"
HelloApp myApp; // Global "application" object
BOOL HelloApp::InitInstance ()
{
 m_pMainWnd = new CFrameWnd();
 m_pMainWnd->Create(0,"Hello, World!!");
 m_pMainWnd->ShowWindow(SW_SHOW);
 return TRUE;
}

이건 그냥 "Hello, World!" 윈도우를 띄우는 코드이다. 중요한 것은 HelleApp 타입의 myApp 객체가 전역 객체라는 것이다. myApp objects는 메인 함수가 실행되기 전에 기본적으로 초기화되게 된다. 그러면서 CWinApp의 생성자가 호출된다. CWinApp class는 framework의 일부로 여러 다른 클래스의 생성자를 불러낸다. 이 생성자들이 실행되는 동안 전역 객체가 프레임 워크에 붙여지고, 나중에 AfxWinMain(MFC의 메인)에 의해 회수된다.

HelloApp::InitInstance member function은 그냥 확인을 위해 있는 부분으로, 이 함수는 AfxWinMain의 실행이 시작된 이후에 호출된다.

본생성자, 파리미터를 가진 생성자, 어떤 함수의 리턴값으로 할당, 동적 초기화 등의 방식으로 전역, 정적 오브젝트을 초기화 할 수 있다.

Caveat 경고

C++에서, 같은 네임스페이스에 있는 객체들은 순서대로 컴파일이 된다. 그러나 static storage duration 객체가 어떤 순서로 컴파일되느냐는 표준화되어있지 않다. 소멸의 순서도 초기화의 순서의 정반대인데, 이게 표준화되어있지 않다는 것이다.

네임스페이스의 객체들은 어떤 함수나 변수가 객체에 접근하기 전에 생성되어야하는데(당연하지...), 이 시점이 메인 전인지 후인지 알 수가 없다. 그래서 static object의 생성자가 다른 static object가 초기화 되기 전에 사용하려고 하는 문제가 발생할 수 있다.

이 idiom은 이런 tatic storage duration의 객체들을 사용하기 때문에 이런 문제에 쉽게 빠질 수 있다.

Known Uses

Microsoft Foundation Classes (MFC)

없음

References

Proposed C++ language extension to improve portability of the Attach by Initialization idiom
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/1995/N0717.htm

profile
미래엔 햄스터를 다운 받을 수 있겠지? 설치류니까...

0개의 댓글

관련 채용 정보