2014-09-11 3 views
1

가정하자 그 청취자를 가정 초를 카운트와 청취자 통지 클래스 SecondTimer 타이머에서 이벤트를 받아 특별한 방법 onTimer()가 있습니다이해 C++ 템플릿 예

template <class TName> 
class SecondTimer 
{ 
public: 
    SecondTimer() : listener(nullptr), stime(0), time(1000), isStarted(false) {} 

    void init(TName * _listener, int _stime) 
    { 
     GASSERT(_listener && "The listener can not be NULL"); 
     listener = _listener; 
     stime = _stime; 
     time = 1000; 
     isStarted = false; 
     listener->onTimer(stime); 
    } 
    inline void start() { isStarted = true; } 
    inline void stop() { isStarted = false; } 
    void Process(int dtime) 
    { 
     if (!isStarted) 
      return; 

     time -= dtime; 
     if (time <= 0) 
     { 
      int ds = 1 - time/1000; 
      time = time % 1000 + 1000; 
      stime -= ds; 
      listener->onTimer(stime); 
      // 
      if (stime <= 0) 
      { 
       isStarted = false; 
      } 
     } 
    } 

private: 
    TName * listener; 
    int stime, time; 
    bool isStarted; 
}; 

을 내가 1000 템플릿으로 사용할를 onTimer(int) 멤버 함수를 구현하는 다른 클래스

프로그램을 만들 때 실제로 어떻게됩니까? 컴파일러가 모든 1000 가지 클래스에 대해 Init()Process() 함수를 복제합니까?

+0

코드에서 실제로 1000 개의 클래스를 사용하는 경우 예. 또한 클래스 수가 많다면 코드에 실제로 잘못된 것이 있음을 의미합니다. –

+0

@ JaviV : 나는 OP가 1000 번 템플릿을 인스턴스화한다고 생각하지 않습니다. 그들은 단지 요점을 만들고 있습니다 : 컴파일러는이 코드를 gazillion 번 복제합니까? 아니면 똑똑 할 것인가? – rodrigo

+0

제가 아는 바로는, 어떻게 든 일반화 할 수 있다고 확신 할 수 있다는 것입니다. –

답변

3

예. 컴파일러는 으로 인스턴스화하고 모든 클래스에 대해 한 번 사용합니다.

가끔 템플릿이 부풀어 오르는 이유는입니다. 부분적으로 그것을 피하는 기술이 있으며 현대 컴파일러는 때로는 영리한 기법을 사용합니다. 그러나 하루가 끝나면 중복 된 코드가 많이 생깁니다.

거기에 몇 가지 컴파일러가 있습니다 (두 개의 동일한 기능을 바이트와 바이트로 컴파일하는 경우 하나만 병합 할 수있는 컴파일러가 기억 나지 않습니다.) 이것은 C++에서 기술적으로 불법입니다. 이 함수에 대한 포인터는 같지 않아도 평등을 비교합니다. 그러나 템플릿 클래스의 많은 함수가 병합됩니다. 불행히도 예제에서는 생성자 start()stop()만이 자격을 얻으며 다른 클래스는 템플릿 클래스를 사용할 가능성이 높습니다.

그리고 이런 종류의 문제는 템플릿을 사용하거나 가상 함수 (인터페이스)가있는 기본 클래스를 작성하는 것이 가치가 있다고 생각하면 해결할 수 있습니다. 그는 개념적으로 가상을 런타임 동안 onTimer (더 느림 &보다 작음) 또는 컴파일 시간 (더 빠른 &보다 빠름)으로 호출합니다. 예를 들어

:

struct TName 
{ 
    virtual void onTimer() =0; 
}; 

class SecondTimer //no template bloat! 
{ 
    /*...*/ 
}; 

PS : 여기있는 대한 컴파일러 병합 할 몇 가지 정보를 추가 할 거라고,하지만 나는 그것을 완벽하게 잘 설명 this answer을 발견했다.

+0

나는 그들이 "합병"하더라도 각자 고유 한 주소를 제공 할 수 있다는 속임수를 기대합니다. 그들에게 각각 1pt의 썽크를주기는 어렵지 않습니다. –

1

컴파일러가 서로 다른 클래스다른 클래스에 대해 Init() 및 Process() 함수를 복제합니까?

예. 이것은 정확히 일어날 것입니다. 컴파일러는 마치이 모든 것을 수동으로 작성한 것처럼 클래스의 전체 코드를 인스턴스화합니다. 그러나 일부 최적화가 가능합니다.