프로그래밍/C++2009. 4. 22. 16:01


구체적 클래스를 정의하지 않고도 서로 관련성이 있거나
독립적인 여러 객체의 군을 생성하기 위한 인터페이스 제공

 정의: 추상적인 부품을 조립해서 추상적인 제품을 만드는 추상적인 공장 같은 패턴
       : 클라이언트에서 구상 클래스를 지정하지 않으면서도 일군의 객체를 생성할 수 있도록 하는 패턴

활용:
         1. 생성되고 구성되고 표현되는 방식과 무관하게 시스템을 독립적으로 만들고자 할 때
         2. 하나 이상의 제품군들 중 하나를 선택해서 시스템을 설정해야 하고 한번 구성한 제품을
            다른 것으로 대체 가능할 때
         3. 관련된 객체군을 함께 사용해서 시스템을 설계하고,
            이 제품이 갖는 제약사항을 따라야 할 때
         4. 제품에 대한 클래스 라이브러리를 제공하고,
            그들의 구현이 아닌 인터페이스를 표현하고 싶을 때
결과:
       1.구체적인 클래스를 분리한다  
         추성클래스가 정의한 인터페이스를 통해서만 클라이언트 프로그램을 작성한다
       2. 제품군을 쉽게 대체할 수 있도록 한다
       3. 제품간의 일관성을 증진한다
       4. 새로운 종류의 제품을 제공하기 어렵다 –
          새로운 제품에 대해 추상 팩토리를 확장하는 것이 어렵다

단점: 클래스 계층이 커질 수 있다

예제코드

#include 
#include 

#include 
#include 

class AbstractProdcutA
{
public:
 AbstractProdcutA ()         {}
 virtual ~AbstractProdcutA() {}
};

class AbstractProdcutB
{
public:
 AbstractProdcutB ()         {}
 virtual ~AbstractProdcutB() {}
};

class AbstractFactory
{
public:
 virtual AbstractProdcutA* CreateProductA (void) = 0;
 virtual AbstractProdcutB* CreateProductB (void) = 0;
};

class ProdcutA1 : public AbstractProdcutA
{
public:
 ProdcutA1()
 {
  std::cout << "ProdcutA1()" << std::endl;
 }
};
class ProdcutA2 : public AbstractProdcutA
{
public:
 ProdcutA2()
 {
  std::cout << "ProdcutA2()" << std::endl;
 }
};
class ProdcutB1 : public AbstractProdcutB
{
public:
 ProdcutB1()
 {
  std::cout << "ProdcutB1()" << std::endl;
 }
};
class ProdcutB2 : public AbstractProdcutB
{
public:
 ProdcutB2()
 {
  std::cout << "ProdcutB2()" << std::endl;
 }
};

class ConcreteFactory1 : public AbstractFactory
{
public:
 virtual AbstractProdcutA* CreateProductA (void)
 {
  return new ProdcutA1();
 }
 virtual AbstractProdcutB* CreateProductB (void)
 {
  return new ProdcutB1();
 }
};

class ConcreteFactory2 : public AbstractFactory
{
 virtual AbstractProdcutA* CreateProductA (void)
 {
  return new ProdcutA2();
 }
 virtual AbstractProdcutB* CreateProductB (void)
 {
  return new ProdcutB2();
 }
};


class Client
{
public:
 void Create (AbstractFactory *f)
 {
  ProdcutA_.reset( f->CreateProductA() );
  ProdcutB_.reset( f->CreateProductB() );
 }

private:
 std::auto_ptr ProdcutA_;
 std::auto_ptr ProdcutB_;
};


int _tmain(int argc, _TCHAR* argv[])
{
 Client client;


 std::cout << "by ConcreteFactory1" << std::endl;
 client.Create ( &ConcreteFactory1() );

 std::cout << std::endl;

 std::cout << "by ConcreteFactory2" << std::endl;
 client.Create ( &ConcreteFactory2() );

 return 0;
}

'프로그래밍 > C++' 카테고리의 다른 글

C++ 디버깅시 TRACE 사용하기  (0) 2009.12.10
STL - List 사용하기  (0) 2009.07.16
파일 입출력 및 링크드 리스트  (1) 2009.05.01
C/C++ 로깅 Facility  (0) 2009.04.25
PVOID  (0) 2009.04.22
Posted by 마블(이환문)
프로그래밍/OpenGL2009. 4. 22. 15:19

1) Picking의 원리
우리가 화면에서 무엇인가를 선택할때는 화면을 보고 그 위에 마우스를 올리고 클릭한다. 그러나 컴퓨터는
멍청해서 이게 어디인지 모른다. 그래서 화면을 다시 그리면서 그리는 붓에 마우스가 걸리면 그제야 그게 어딘
지 알게된다. 예를들어 아래 표에서 화살표 위치를 픽킹했다면 컴터는 화면을 다 다시 그리면서 저 칸에 그림
을 그리게 되면 "엇!! 여기 마우스가 있었군!!" 하고 알게된다.

위와 같은 원리로 픽킹을 하게 되므로 다시 그릴 때 마우스 위치에 걸리면 현재 자기가 무엇을 그리는지를
알아야 되고(Name을 이용) 검사할 칸의 크기를 알아야 되고(int형으로 가로세로 픽셀수를 정해줌) 몇 개가 어
느 위치에 그릴 때 선택되었는지(버퍼)를 알아야 한다.

2) Picking 예제

 

//픽킹을 위한 버퍼의 크기인데 넉넉히 줘도 된다. 모자라면 안된다.
#define BUFFER_LENGTH 64
//픽킹으로 사용되는 입력은 마우스의 좌표이다.
void PickingPlane(int mx, int my)
{
GLuint selectBuff[BUFFER_LENGTH];
GLint hits, viewport[4];
glSelectBuffer(BUFFER_LENGTH, selectBuff); //Picking에 사용될 버퍼를 설정한다.
glGetIntegerv(GL_VIEWPORT, viewport);//변환에 필요한 정보인 viewport정보를 얻어온다.
//여기서 부터는 랜더링이 화면에 되지 않는다. 즉, 앞에서 말한것처럼 컴퓨터가 마우스가 어디서
//걸리는지 찾기 위해서 다시 혼자 그려보는 그런 단계가 시작된다.
glRenderMode(GL_SELECT);
//현재의 프로젝션 메트릭스 저장.
//지금부터 설정되는 메트릭스의 순서에 유의해야 한다. 기본이 Modelview인데 새로 프로젝션을 설정하는데
//이후에 생긴 변환이 현재 사용하는 변환에 영향을 주지 않도록 push matrix를 하는것이다.
glMatrixMode(GL_PROJECTION);
glPushMatrix();//저장.
//랜더링과 같은 환경을 구현하기 위해서 똑같이 다시 그릴수 있는 변환을 한다.
glLoadIdentity();
gluPickMatrix(mx,viewport[3]-my,2,2,viewport);
int w = viewport[2], h = viewport[3];
if(w<=h)
glOrtho(-BASE_UNIT,BASE_UNIT,
-BASE_UNIT*(GLfloat)h/(GLfloat)w,BASE_UNIT*(GLfloat)h/(GLfloat)w
,-BASE_UNIT,BASE_UNIT);
else
glOrtho(-BASE_UNIT*(GLfloat)w/(GLfloat)h,BASE_UNIT*(GLfloat)w/(GLfloat)h,
-BASE_UNIT,BASE_UNIT,
-BASE_UNIT,BASE_UNIT);
//똑같이 그리기 위해 변환과 네임을 쓰는건 다 그려준다.
glMatrixMode(GL_MODELVIEW);
glPushMatrix();//다른 부분에 영향을 주지 않도록 메트릭스 저장
RenderInit();
//다 똑같은데 이 함수만 다르다. 즉, 이름을 정해가면서 그린다.(뒤에서 다룸)
DrawCube(BASE_UNIT,true);
glPopMatrix();
//이상은 네임을 로드/푸시하는것 말고는 보통 상태에서 그리는 것과 같다.
//앞에서 저장한 프로젝션 메트릭스를 복구하기 위해 프로젝션으로 변경.
glMatrixMode(GL_PROJECTION);
glPopMatrix();//복구
//랜더링을 모두 실행.- 이제 어딘지 검사하기 위해서 OpenGL혼자 그려본 것이 끝났다.
//그럼 어디서 걸렸는지 녀석에게 물어보자.
glFlush();
//Picknig을 종료하면서 스택을 얻어온다. 즉, 녀석에게 니가 아는걸 알려달라고 하는 것과 같다.
hits = glRenderMode(GL_RENDER);
//다시 그림을 그리기 위해서 모델뷰로 변경한다. 이제부터는 다시 화면에 그려진다.
glMatrixMode(GL_MODELVIEW);
}

'프로그래밍 > OpenGL' 카테고리의 다른 글

옥트리(octree)  (0) 2009.04.25
OpenGL Viewing  (0) 2009.04.24
OpenGL 기초  (1) 2009.04.23
void glutIdleFunc(void (*func)(void))  (0) 2009.04.22
void glutPostRedisplay(void)  (0) 2009.04.22
Posted by 마블(이환문)

STL 사용시 벡터 사용시 이런 에러가 났다

에러 코드 : IntVector.insert(&IntVector[3], 11)

해결방안:

 vector<int>::iterator t = IntVector.begin();
 advance(t, 3);
 IntVector.insert(t, 11);

advance()는 반복자를 지정한 숫자만큼 이동시켜주는 함수이다

Posted by 마블(이환문)