(C++ : Design-pattern) Container Pattern

Posted by : at

Category : Cpp   Design-pattern


#include <iostream>
using namespace std;

struct Node
{
    int data;       // int말고 다른 변수를 넣고싶다?
    Node* next;
    Node(int d, Node* n) : data(d), next(n) {}
};

class slist
{
    Node* head = 0;
public:
    void push_front(int n) { head = new Node(n, head); }
    int front()            { return head->data; }
};

int main()
{
    slist s;

    s.push_front(10);
    s.push_front(20);
    s.push_front(30);
    s.push_front(40);

    int n = s.front();
}
struct object
{
    virtual ~object() {}
};
// 모든 클래스는 object로 부터 파생되어야 한다.

class Dialog : public object{};
// ...

struct Node
{
    object* data;       // int말고 다른 변수를 넣고싶다?
    Node* next;
    Node(object* d, Node* n) : data(d), next(n) {}
};

class slist
{
    Node* head = 0;
public:
    void push_front(int n) { head = new Node(n, head); }
    object* front()            { return head->data; }
};

int main()
{
    slist s;

    s.push_front(new Point);
    s.push_front(new Dialog);       
    // Point만 담는것이 아니랴 Dialog까지? -> type의 안정성이 떨어진다.

    Point* p = static_cast<Point*>(s.front());      
    // 반드시 캐스팅을 해야한다.

    s.push_front(10);               
    // primitive type은 저장할 수 없다.
}
  • 장점 :
    • 코드 메모리가 증가 하지 않는다.
  • 단점 :
    • 타입 안정성이 떨어진다.
    • 컨테이너에서 요소를 꺼낼 때, 반드시 캐스팅 해야한다.
    • int, double 등의 primitive type은 저장할 수 없다.
    • 별도의 Integer : public object 등의 타입이 필요하다.

template으로 위 단점을 해결해 보자.

template<typename T> struct Node
{
    T data;
    Node* next;
    Node(const T& d, Node* n) : data(d), next(n) {}
};

template<typename T> class slist
{
    Node<T>* head = 0;
public:
    void push_front(const T& n) { head = new Node<T>(n, head); }
    T front()            { return head->data; }
};

int main()
{
    slist<int> s;

    s.push_front(10);       // primitive type 저장가능
    // s.push_front(new Dialog);   // type안정성 확보

    int n = s.front();      // 캐스팅 필요없음

    // ...
}

template 기반 컨테이너

  • 장점 :
    • 타입 안정성이 뛰어나다
    • 캐스팅이 필요 없다.
    • primitive type 저장할 수 있다.
  • 단점 :
    • 코드 메모리가 증가한다.(매 type에 따라 매모리 증가)
struct Node
{
    void* data;
    Node* next;
    Node(void* d, Node* n) : data(d), next(n) {}
};

class slistImp
{
    Node* head = 0;
public:
    void push_front(int n) { head = new Node(n, head); }
    void* front()            { return head->data; }
};

template<typename T> class slist : public slistImp
{
public:
    inline void push_front(T n) { slistImp::push_ront(void*)n); }      // 중간에서 캐스팅만 담당해준다.
    inline T front()            { return (T)slistImp::front(); }
};

int main()
{
    slist<int> s;

    s.push_front( 10 );
    int n = s.front();
}
  • thin template 기반 컨테이너
    • 템플릿에 의한 코드 중복을 줄이기 위한 기술
    • void* 등으로 내부 자료구조를 구성하고, 캐스팅을 위한 템플릿을 제공한다.
    • Synbian OS, Android 등 모바일 용 라이브러리에서 많이 사용하는 기술

About Taehyung Kim

안녕하세요? 8년차 현업 C++ 개발자 김태형이라고 합니다. 😁 C/C++을 사랑하며 다양한 사람과의 협업을 즐깁니다. ☕ 꾸준한 자기개발을 미덕이라 생각하며 노력중이며, 제가 얻은 지식을 홈페이지에 정리 중입니다. 좀 더 상세한 제 이력서 혹은 Private 프로젝트 접근 권한을 원하신다면 메일주세요. 😎

Star
Useful Links