#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 등 모바일 용 라이브러리에서 많이 사용하는 기술