티스토리 툴바



'c++'에 해당되는 글 53건

  1. 2010/01/01 CxImage의 MakeBitmap를 잘못 사용하면 페이지파일(PF), 메모리 사용량이 늘어난다. (1)
  2. 2009/08/05 [VC++] 응용 프로그램 구성이 올바르지 않기 때문에 이 응용 프로그램을 시작하지 못했습니다. 오류 해결 방법
  3. 2008/08/21 [MFC] 폴더만 탐색 및 xml 데이터 생성 (1)
  4. 2008/08/20 [MFC] XML의 계층구조 데이터를 읽어 들이는 코드 (GetchildNodes, getAttribute, nextNode)
  5. 2008/07/30 [MFC] CScrollView와 줌인 줌아웃 처리.
  6. 2008/07/17 윈도우즈 업데이트 오류날때.. 레지스트리 등록 필수!!
  7. 2008/07/09 [MFC] CxImage 1비트 이미지 만들기...
  8. 2008/06/25 [MFC, DLL] Image를 그레이 스케일 버퍼로 생성후 그려주는 다이얼로그 소스
  9. 2008/06/23 [MFC, DLL] Image를 표시해 주는 다이얼로그 소스
  10. 2008/06/06 C++용 CxImage 6.0 - Library 코드
  11. 2008/06/04 C++ 객체 팩토리(Object Factory)
  12. 2008/05/15 [C++] 타일 만들기.. (1)
  13. 2008/05/10 [Design Pattern] 중재자 ( Mediator )
  14. 2008/05/05 [C++, 템플릿] 템플릿의 부분 특화 (3)
  15. 2008/05/05 [C++, 템플릿] 템플릿 템플릿 인자를 통한 단위전략 확장
2010/01/01 23:29

CxImage의 MakeBitmap를 잘못 사용하면 페이지파일(PF), 메모리 사용량이 늘어난다.


MFC의 Dialog 베이스를 사용해서 폼을 하나 제작합니다.
그리고 picture Box 를 하나 제작한 후에 CxImage를 사용해서 png 파일을 하나 로드 한후에
picture Box에 SetBitmap 를 하고 나서 이걸 다른 형태로 테스트를 진행해 봤습니다.

기본 코드는 아래와 같아요.

// CxImage 객체 생성
m_pImage = new CxImage("D:\\Test.png", CXIMAGE_FORMAT_PNG);

// PictureBox 컨트롤에 CxImage 이미지 연동
m_pic.SetBitmap( m_pImage->MakeBitmap() );

이렇게 하고 나서 실행 하고, 종료 하게 되면 크게 문제는 안되는듯 하다.

이걸 다른 형태로 테스트를 해봤다.
타이머를 통해서 CxImage 객체 두개의 Bitmap를 m_pic(PictureBox) 컨트롤에 SetBitmap를 반복해서 처리해봤다.

void CPngToBitmapDlg::OnTimer(UINT nIDEvent)
{
 static bool bFirst = false;
 static HBITMAP hBitmap = NULL;

 if( bFirst == false )
 { 
  hBitmap = m_pic.SetBitmap( m_pImage2->MakeBitmap() );
 }
 else
 {
  hBitmap = m_pic.SetBitmap( m_pImage->MakeBitmap() );
 }

 ::DeleteObject( hBitmap );

 //
 bFirst = !bFirst;

 m_loopCount++;
 UpdateData(false);
 

 CDialog::OnTimer(nIDEvent);
}

위의 붉은색 코드를 하지 않고 계속해서 SetBitmap을 하게 되면
페이지파일(PF)가 계속 증가 하는 것을 볼 수 있다.

앞으로 코드 구현을 할때 하나 하나 단위테스트를 통해서 반복적인 메모리 및 GDI 사용량 등을
체크 하고 좀 안정성 있는 프로그램을 하도록 해야 할거 같다.

저작자 표시 비영리 변경 금지
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 1
2009/08/05 15:26

[VC++] 응용 프로그램 구성이 올바르지 않기 때문에 이 응용 프로그램을 시작하지 못했습니다. 오류 해결 방법



VC++ 2008을 작업 하다 보면 다른 pc에서 이런 오류 메시지를 종종 보게 된다.
이때 해결 방법은 몇가지로 나눠 진다.

1. DLL을 같이 배포
  - C:\Program Files\Microsoft Visual Studio 9.0\VC\redist 폴더 안에 있는 debug, release 의 내용을 복사해서 같이 배포 한다.
  - 사실 이렇게 해봤지만. 되지 않을때가 많다.

2. 배포 패키지를 사용
  - 어떤 개발툴(2005, 2008) 둘중에 하나를 쓰게 되는데요. 이때 선택해서 배포 패키지를 깔아서 써야 한다.




  - 위의 3개 중에서 내가 테스트 할때는 2008로 개발했을때인데.. 이때 sp1 빼고 2008 배포 패키지만 깔아도 될때도 있었다.

Tip :
  - 컴파일 할때 보면 "다중 스레드 디버그 DLL", "다중 스레드 디버그" 두개가 실행파일의 dll 관계를 보면 좀 틀려 보이긴 한다. 어쩔땐 이걸 해결하면 될때도 있다.. 쩝.. 너무 귀찮다.

[아래 화면은 Tip에 적어 놓은, 걸 Depends로 찍어 본것..]
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 0
2008/08/21 02:55

[MFC] 폴더만 탐색 및 xml 데이터 생성

특정 폴더를 기준으로 하위 폴더를 찾아 내는 코드 입니다.
그리고 그 폴더 내용을 xml 형태로 만들어 주는 코드도 포함되어 있습니다.
xml 데이터로 만들어진 내용은 CEdit 컨트롤에 표시되며, 그 내용을
저장할 수 있습니다.


하위 폴더를 검색하는 코드 표시하기

폴더탐색 및 트리노드 추가 표시하기

트리 노드 전체 탐색 표시하기

트리노드탐색 및 xml 생성 표시하기

CEdit 내용을 파일에 기록 표시하기

관련 소스 :



.

크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 1
2008/08/20 22:40

[MFC] XML의 계층구조 데이터를 읽어 들이는 코드 (GetchildNodes, getAttribute, nextNode)

MFC에서 xml 데이터를 읽어 들이는 예제입니다.
아래의 내용을 계층구조를 통해서 읽어 들이게 됩니다.
자세한 소스는 소스 코드를 참조 하세요.
  - XmlParser.h, cpp

[xml 샘플]

<?xml version="1.0" encoding="EUC-KR"?>

<PATHS>
 <PATH NAME="Install Files">
  <PATH NAME="Dev">
  </PATH>
  <PATH NAME="Dev2">
  </PATH>
  <PATH NAME="Dev3">
   <PATH NAME="Dev3_a">
   </PATH>
   <PATH NAME="Dev3_b">
    <PATH NAME="Dev3_b_a">
    </PATH>
    <PATH NAME="Dev3_b_b"/>
   </PATH>
  </PATH>
 </PATH>
 <PATH NAME="temp">
  <PATH NAME="temp_a"/>
  <PATH NAME="temp_b">
   <PATH NAME="temp_b_a">
   </PATH>
   <PATH NAME="temp_b_b">
    <PATH NAME="temp_b_c"/>
   </PATH>
  </PATH>
 </PATH>
</PATHS>

계층 구조를 읽어 들이는 코드 (재귀호출)

1. 초기화 및 도입부

 ///
 MSXML2::IXMLDOMNodePtr nodeList = m_pDoc->selectSingleNode( Token.c_str() );
 _bstr_t bsElements("PATHS");

 if ( nodeList )
  FindName( nodeList->GetchildNodes() );

 nodeList.Release();

2. 재귀호출 부분

int tabCount = 0;

HRESULT CXmlParser::FindName( MSXML2::IXMLDOMNodeListPtr& lparam )
{
 long elementCount = lparam->Getlength();
 for( int i = 0; i < elementCount; i++ )
 {
  MSXML2::IXMLDOMElementPtr Element = lparam->nextNode();
  if( Element == NULL )
   break;

  _bstr_t bsNodename = Element->GetnodeName();
  _bstr_t bsElement("PATH");
  if( bsNodename == bsElement )
  {
   _bstr_t bsname("NAME");
   _variant_t varElementName = Element->getAttribute(bsname);

   // 해당하는 엘러먼트 Name의 이름 == 폴더 이름을 의미한다.
   CString strName;
   strName.Format( "%S", varElementName.bstrVal );    

   // 탭 카운터를 통한 출력
   CString strTabMergy;
   for( int tc = 0; tc < tabCount; tc++ )
   {
    strTabMergy += "\t";
   }
   strTabMergy += strName;
   TRACE( "%s\n", (LPSTR)(LPCSTR)strTabMergy);

   MSXML2::IXMLDOMNodeListPtr childElementlist = Element->GetchildNodes();
   if( childElementlist )
   {
    tabCount++;
    FindName( childElementlist );
   }
  }

  Element.Release();
 }

 tabCount--;
 lparam.Release();

 return S_OK;
}

아래의 콘솔 화면 내용입니다.

사용자 삽입 이미지


소스 코드 :


.

크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 0
2008/07/30 00:26

[MFC] CScrollView와 줌인 줌아웃 처리.

기본 소스는 아래 주소의 포스트를 사용했어요.. ^^
[MFC] Ruler 소스.. 메모리 DC 사용한 자연스러운 효과구현..


중점 :
  1. 줌인 줌아웃 처리를 위한 float 변수를 하나 추가 했습니다.
  2. ScrollView의 페이지 크기를 저장하는 CSize 변수를 하나 추가 했습니다.
  3. 방향키 UP, DOWN 을 사용해서 줌인, 줌아웃 처리를 보여 줍니다.

이제 설명을 시작하겠습니다.

Ruler 보완

Ruler의 기존 소스를 보게 되면 마우스로 스크롤 할때 Ruler가 따라 가지 않습니다.
기존 코드를 볼가요?
 // 기본 Ruler
 CRect rulerRect;
 rulerRect.left = scrollPosition.x;
 rulerRect.right = rulerRect.left + curArea.Width();
 rulerRect.top = scrollPosition.y;
 rulerRect.bottom = rulerRect.top + 20;
 m_RulerHorz.Draw( pDC, rulerRect.left, rulerRect.top, rulerRect.Width(), rulerRect.Height(), scrollPosition.x );

분명히 scrollPosition.y를 해줬는데도 안됩니다.
이걸 해결 하기 위해서는 휠을 움직여서 화면을 업데이트 한 것이기 때문에
아래의 OnMouseWheel함수를 오버라이드(?) 해서 Invalidate()를 해줘야 됩니다.

BOOL CRulerSampleView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
 Invalidate();
 return CScrollView::OnMouseWheel(nFlags, zDelta, pt);
}

그리고 Scroll의 Bar를 움직여도 화면이 업데이트 되어야 하기 때문에 아래의 함수들도 같이 처리

void CRulerSampleView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
 Invalidate( true );
 CScrollView::OnHScroll(nSBCode, nPos, pScrollBar);
}

void CRulerSampleView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
 Invalidate( true );
 CScrollView::OnVScroll(nSBCode, nPos, pScrollBar);
}

이렇게 하고 나면 휠 또는 스크롤바를 움직여도 Ruler가 자연스럽게 화면에 보이는걸 알 수 있습니다.

자자..
이제 줌인 줌아웃 처리를 해볼까요..


줌인 줌아웃 처리를 위해서 아래의 코드를 RulerSampleView.h 에 추가 합니다.
 CSize     m_PageSize;
 float     m_Zoom;

그리고 RulerSampleView.cpp 에는 아래와 같이 해봅시다.

> 우선 줌 성분 초기화를 생성자 함수에 추가
m_Zoom = 1.f;

> ScrollVew이기 때문에 페이지의 크기를 추가
void CRulerSampleView::OnInitialUpdate()
{
 CScrollView::OnInitialUpdate();

 m_PageSize = CSize( 1000, 1000 );
 SetScrollSizes(MM_TEXT, m_PageSize);
}

> 드로잉 코드에 m_Zoom을 적절하게 수정해 줍니다.
테스트를 위한 위치값을 10개를 생성했습니다. 이건 코드 보시면 알수 있어요..
드로잉 할때 아래와 같이 처리 합니다.
 vector< CPoint >::iterator iter;
 for( iter = m_TestData.begin(); iter != m_TestData.end(); iter++ )
 {
  CRect rect;
  rect.left  = (*iter).x;
  rect.top  = (*iter).y;
  rect.right  = rect.left + 50;
  rect.bottom  = rect.top + 50;

  rect.left  *= m_Zoom;
  rect.top  *= m_Zoom;
  rect.right  *= m_Zoom;
  rect.bottom  *= m_Zoom;

  pDC->FillRect( &rect, &redbrush );
 }
위의 붉은 부분을 m_Zoom으로 곱해줍니다.

> 이렇게 하고 나서 이제 이벤트를 추가해줘야 겠죠.
방향키를 통해서 줌인 줌아웃 성분을 증가 감소 합니다.

void CRulerSampleView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
 if( nChar == VK_UP )
 {
  m_Zoom -= 0.1f;

  CClientDC dc(this);
  m_RulerHorz.CreateDC( &dc, 10000, 20, m_Zoom );

  m_PageSize = CSize( 1000*m_Zoom, 1000*m_Zoom );
  SetScrollSizes(MM_TEXT, m_PageSize);

  Invalidate();
 }

 if( nChar == VK_DOWN )
 {
  m_Zoom += 0.1f;

  CClientDC dc(this);
  m_RulerHorz.CreateDC( &dc, 10000, 20, m_Zoom );

  m_PageSize = CSize( 1000*m_Zoom, 1000*m_Zoom );
  SetScrollSizes(MM_TEXT, m_PageSize);

  Invalidate();
 }

 CScrollView::OnKeyDown(nChar, nRepCnt, nFlags);
}

위의 코드에서 보듯이 Ruler도 줌 성분이 달라지면, Ruler의 줌 성분을 보정해서 메모리 DC를 생성합니다.
그리고 ScrollView의 페이지도 m_Zoom에 따라서 사이즈를 제조정 해줍니다.

이렇게 하면 아래와 같은 프로그램을 만들 수 있습니다.

사용자 삽입 이미지
사용자 삽입 이미지

관련샘플 :


.


.


크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 0
2008/07/17 09:13

윈도우즈 업데이트 오류날때.. 레지스트리 등록 필수!!

윈도우즈 업데이트 할때 일부 문제로 인해서 업데이트가 수행되지 않습니다.
아래와 같이 서비스 종료 후에 업데이트 dll을 등록해 주고 서비스 재시작 해주면 된다.

C:\>net stop wuauserv
C:\>regsvr32 %windir%\system32\wups2.dll
C:\>net start wuauserv

크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 0
2008/07/09 21:03

[MFC] CxImage 1비트 이미지 만들기...

흑백의 이미지를 CxImage로 만들때 8비트, 24비트의 이미지로 만들 필요가 없습니다.
이때 1비트의 이미지로 해도 충분한 공간이 나온다는 얘긴데요.
아래의 코드는 1비트의 이미지를 생성하는 코드 입니다.

void GToleranceImage::MakeBuffer2Image()
{
 SAFE_DELETE( _pbuffer2Image );
 assert( _pbuffer2Image == NULL );
  // 넓이와 폭을 사용해서 이미지 버퍼를 생성합니다.
  // 이때 1비트의 이미지로 설정합니다.
 _pbuffer2Image = new CxImage( _width, _height, 1, CXIMAGE_FORMAT_BMP );

  // 이미지의 팔레트를 지정합니다.
  // 흑백 이미지를 만들거기 때문에 0번과 1번 팔레트를 설정합니다.
 _pbuffer2Image->SetPaletteColor(0, RGB(0, 0, 0));
 _pbuffer2Image->SetPaletteColor(1, RGB(255, 255, 255));

  // 해당 내용을 추가합니다.
  // SetPixelColor로 하지 않고, SetPixelIndex로 하게 됩니다.
 for( int y = 0; y < _height; y++ )
 {
  for( int x = 0; x < _width; x++ )
  {
   BYTE color = _bufferXY[y][x];
   if( color == 255 )
    _pbuffer2Image->SetPixelIndex( x, y, 1 );
   else
    _pbuffer2Image->SetPixelIndex( x, y, 0 );
  }
 }
 _pbuffer2Image->Flip();
}

크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 0
2008/06/25 02:29

[MFC, DLL] Image를 그레이 스케일 버퍼로 생성후 그려주는 다이얼로그 소스

사용자 삽입 이미지

그레이 스케일로 표현해주는 코드가 일부 들어가 있는 소스입니다.
MFC DLL 형태로 제작되어 있으며, 바로 이전의 게시물과 거의 동일한 구조입니다.
몇가지 단위 테스트를 위해서 제작된 샘플 프로젝트입니다.

관련 소스 :


.
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 0
2008/06/23 18:36

[MFC, DLL] Image를 표시해 주는 다이얼로그 소스

사용자 삽입 이미지

MFC DLL : 한장의 이미지를 보여 주는 dll 파일입니다.
                현재 jpg의 파일만 인코딩이 가능합니다.
                (이 부분은 확장자를 사용해서 처리 하시면 됩니다. 아직 그건 추가 하지 않았네요. )

사용시에는 아래의 코드를 이용 하시면 됩니다.

 CDlgImage dlg( "E:\\Gsi_Project\\정상옥_프로젝트\\Project\\2008_06_23_LAM_ModuleTest\\bin\\blue.jpg" );
 dlg.DoModal();

이외의 생성자 인자로서는 해당 width, height를 입력해줄 수 있으며,
내부 코드에서는 해당 다이얼로그에 맞도록 리셈플링 처리가 되어 있습니다.


실행파일 :



.

프로젝트 파일 :


.

크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 0
2008/06/06 16:28

C++용 CxImage 6.0 - Library 코드


http://www.codeproject.com/KB/graphics/cximage.aspx

CxImage 6.0 Full 코드를 컴파일 해서
png, jpg, bmp, gif 를 지원하도록 처리 해서 생성해 놓은 코드 임.



.
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 0
2008/06/04 10:53

C++ 객체 팩토리(Object Factory)

여러개의 객체를 생성하는 코드를 아래와 같이 일반적으로 사용합니다.

class Shape {};
class Line_ : public Shape  { public: Line_()   { printf("create Line\n");  } };
class Polygon_ : public Shape { public: Polygon_()  { printf("create Polygon\n"); } };
class Circle_ : public Shape  { public: Circle_()  { printf("create Circle\n"); } };

namespace DrawingType
{
 const int
  LINE = 1,
  POLYGON = 2,
  CIRCLE = 3;
};


Shape* Load( int drawingType )
{
 Shape* p;

 switch( drawingType )
 {
  using namespace DrawingType;
 case LINE:
  {
   p = new Line_();
  }
  break;

 case POLYGON:
  {
   p = new Polygon_();
  }
  break;

 case CIRCLE:
  {
   p = new Circle_();
  }
  break;
 }

 return p;
}

사용은 아래와 같이
 Shape* p;

 p = Load( DrawingType::LINE );
 delete p;
 p = Load( DrawingType::POLYGON );
 delete p;
 p = Load( DrawingType::CIRCLE );
 delete p;

하지만 이런 코드의 경우 객체의 추가로 인한 오버헤드가 커지게 됩니다.
그럼 이런 경우 어떻게 조금더 최적화가 가능해질것인가를 생각해 보면 아래와 같이 될 수 있습니다.

//
class ShapeFactory
{
 ShapeFactory() {}

public:
 typedef Shape* (*CreateShapeCallback)();

 static ShapeFactory& GetInstance()
 {
  static ShapeFactory sf;
  return sf;
 }

private:
 typedef std::map< int, CreateShapeCallback > CallbackMap;

public:
 bool RegisterShape( int ShapeId, CreateShapeCallback CreateFn )
 {
  return callbacks_.insert(
   CallbackMap::value_type( ShapeId, CreateFn ) ).second;
 }

 bool UnRegisterShape( int ShapeId )
 {
  return callbacks_.erase( ShapeId ) == 1;
 }

 Shape* CreateShape( int ShapeId )
 {
  CallbackMap::const_iterator I = callbacks_.find( ShapeId );
  if( I == callbacks_.end() )
   return NULL;

  return (I->second)();
 }

private:
 CallbackMap callbacks_;
};


namespace
{
 Shape* CreateLine()
 {
  return new Line_;
 }

 Shape* CreatePolygon()
 {
  return new Polygon_;
 }

 Shape* CreateCircle()
 {
  return new Circle_;
 }
 };

// 사용할때

 // 객체 레지스트리에 등록
 ShapeFactory::GetInstance().RegisterShape( DrawingType::LINE, CreateLine );
 ShapeFactory::GetInstance().RegisterShape( DrawingType::POLYGON, CreatePolygon );
 ShapeFactory::GetInstance().RegisterShape( DrawingType::CIRCLE, CreateCircle );

 p = ShapeFactory::GetInstance().CreateShape( DrawingType::LINE );
 delete p;
 p = ShapeFactory::GetInstance().CreateShape( DrawingType::POLYGON );
 delete p;
 p = ShapeFactory::GetInstance().CreateShape( DrawingType::CIRCLE );
 delete p;

객체를 레지스트리에 등록하고
사용하게 됩니다.

이때 더 나아간다면 템플릿을 사용해서 예외 처리를 조금더 기능적으로 해줄 수 있습니다.

크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 0
2008/05/15 02:04

[C++] 타일 만들기..

데모로 만들어 보고 있는 타일 생성기 초안입니다.

타일을 하나하나 마우스로 찍어서 하는건 너무 노가다라고 생각 되고,
스타 크래프트의 맵 에디터는 신의 경지고 ^^..

우선 아래와 같은 실행 파일을 하나 제작해 봤습니다.
사용자 삽입 이미지

기본 토대는 여러가지의 카테고리를 가진 기본 타일이 존재 하고 그 타일의 주변을 감싸는 테두리를 검색한 후에 그 검색한 테두리 부분을 부드럽게 연결해 주는 겁니다.

관련코드 :


.
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 1
2008/05/10 00:11

[Design Pattern] 중재자 ( Mediator )

중재자 ( Mediator )

의도

  • 한 집합에 속해 있는 객체의 상호작용을 캡슐화
  • 객체 사이의 소결합 (loose coupling)
  • 객체의 상호작용을 독립적으로 다양화 시킴

동기

  • 객체 지향 개발 방법에 있어서 행동을 여러개의 객체로 분산시키고 있습니다.
  • 분할된 객체들의 관리가 제대로 되지 못하면 객체 간 상호작용의 급증으로 인한 오류를 범할 수 있습니다.

MFC의 개발을 하다 보면 화면 UI 및 데이터간의 연동이 필요 하게 됩니다.
리스트 박스의 셀렉트가 되면 해당 에디터 박스에 출력을 하고, 그 반대의 경우도 존재 할 수 있습니다.
이러한 경우 객체 대 객체 간의 데이터 접근 방법을 사용하게 되면 결합도가 높아지면서 코드가 복잡해 지고,
재 사용성을 떨어 트리게 됩니다.

이때, 중재자 객체를 활용하면 여러 객체가 처리 하는 행동들을 하나의 객체에서 처리 하게 되면서 이런 문제점들을 해결할 수 있습니다.

중재자 객체는 객체 그룹 간의 상호작용을 제어하고 조화를 이루는 역활을 합니다.
즉, 객체 사이의 연결 정도가 줄어 들게 됩니다.

하나의 예를 들어 보겠습니다.
리스트 박스와 에디터 박스가 있다고 합시다.

  1. 리스트 상자는 지시자 객체에게 자신이 변경되었음을 통보 합니다.
  2. 지시자는 리스트 상자에서 선택된 부분이 무엇인지 알아옵니다.
  3. 지시자는 입력 창에 선택 부분을 전달합니다.
  4. 입력 창에는 어떤 값이 포함됩니다. 지시자는 관련된 버튼을 활성화 시킵니다.

UML 내용을 한번 볼께요.

사용자 삽입 이미지

위의 것은 실제적인 구현한 내용을 토대로 제작된 UML 과 아래의 기본 구조모양의 UML을 보실 수 있습니다.

자세한 소스 코드는 오늘은 올리기 힘들듯 합니다. -.-
한번 데모로 작성해 보고 올려야 할듯 합니다.
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 0
2008/05/05 01:38

[C++, 템플릿] 템플릿의 부분 특화

template< class T1, class T2 >
class Test
{
};

이런 클래스가 있다고 합시다.
우리는 이 클래스가 두개의 템플릿 인자를 받아 들인다는 걸 알고 있습니다.

Test< Ca, Cb > A;
A a;

이런 식이 되는 거죠.

그렇다면 저희가 작업 할때 Test 라는 템플릿 클래스를 놓고 특정 타입에 대해서
특화 되게 구현하고 싶은 경우가 있을거예요.

template< class T1, class T2 >
class Test {};

template <>
class Test< CT, CU > {};

이렇게 두개의 같은 클래스이지만 하나는 CT, CU의 명시적으로 특화된 클래스가 또 하나 존재를 하게 되면 만약 코딩을 통해서 CT, CU가 들어 오게 되면 아래의 클래스가 동작 되게 되는거죠.

바로 이게 부분 특화 입니다.

이때 부분적으로 특화를 하고 싶다면 아래와 같은 클래스를 하나 추가 하면 되요

template < class T1 >
class Test< T1, CU > {};

앞의 T1은 모든 객체를 다 받아 들이고 뒤의 CU는 명시적으로 선언을 해놨어요.
이게 바로 부분 특화라는 거죠 ^^

하나더 해볼까요?.

Button 이라는 클래스가 있다고 합시다. 모든 Button과 CU에 대해서 특화 시키고자 한다면...

template < class T1 >
class Test< Button<T1>, CU > {};

이렇게 하면 되죠 ^^

템플릿의 장점은 참 많네요..

ps. 지적 및 조언 및 질문 해주시면 고맙겠습니다.

크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 3
2008/05/05 01:22

[C++, 템플릿] 템플릿 템플릿 인자를 통한 단위전략 확장

제목이 참 아리송 합니다. ^^
하지만 내용을 읽고 나면 이해가 될거예요..

이전의 포스트 를 우선 보시고 이 내용을 꼭 보셔야 합니다.

우선 이전의 내용을 한번 짚어 보면...

단위 전략을 통해서 객체 생성에 new, malloc를 선택적으로 해줄 수 있다는 거죠.

typedef WidgetManager< OpNewCreator<CTest> > MyWidgetMgr;
MyWidgetMgr a;

이런 코드를 사용해서 CTest를 특화 되게 구현할 수 있게 되는거죠.
즉, CTest 의 객체를 new, malloc를 선택해서 처리가 가능하다는 말이 됩니다.

그런데 이때 고민이 좀 됩니다.
뭐냐 하면 내부에서

CTest* p = CreationPolicy().Create( p2 );

이 코드를 사용했어요. CTest 를 특화 했기 때문에 CTest만을 사용하게 되는거예요.

난 다른 객체들도 메니져 안에서 다 관리 해주고 할려고 하면 에러가 나서 안되는거죠.

그래서 이 포스트의 주제가 나옵니다.
기본 선언은 비슷하게 구현하되 내부에서 다른 객체를 생성하는 것도 가능하게 말이죠.

우선 아래의 코드를 한번 보고 해요.

template < class T >
struct OpNewCreator
... 생략

template < class T >
struct MallocCreator
... 생략

template < template < class > class CP >
class CTestMgr : public CP<CTest>
{
public:
 CTestMgr()
 {
  CTest2* ptest2 = CP<CTest2>().Create();
 }
 ~CTestMgr() {}
};


위의 코드를 보면 이런 코드가 보입니다.
template < template < class > class CP >
이게 바로 템플릿 템플릿 인자를 통한 단위전략의 중요한 부분이라고 보여 집니다.

즉 이렇게 해서 CP<CTest> 라고 명시적으로 적어 주게 되면 아래와 같은 코드를 통해서 메니져를
처리할 수 있습니다.

typedef CTestMgr< OpNewCreator > MyTestMgr;

원래는 OpNewCreator 에 다른 인자를 더 넣어 주어야 하지만 명시적으로 처리가 되었기 때문에
추가를 해줄 필요가 없게 됩니다.

이렇게 하고 나면...

바로 아래와 같이 내부에서 다른 객체를 사용할 수 있게 됩니다.

CTest2* ptest2 = CP<CTest2>().Create();

어때요?.. CP의 단위 전략을 사용하면서 내가 원하는 다른 객체를 적용할 수 가 있게 됩니다.

Tip.
여기서 보시면 CP에 CTestMgr를 연결할 수도 있게 되요.
CTestMgr* p = CP<CTestMgr>().Create(); 이렇게요.

이건 나중에 템플릿을 여러개로 사용하면서 현재 클래스를 체크를 해준다거나 하는
여러가지 기능을 처리 하는 부분에서 또 설명이 나오네요..

오늘 내용은 여기 까지 ^^

ps. 지적 및 조언 및 질문 해주시면 고맙겠습니다.

크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 0