2011-01-23 6 views
0

그래서 저는 C++에 대해 매우 신중합니다. 그리고 템플릿을 이해하지 못하고 tham thow를 사용하는 방법을 wikipedia로 바꾸고 C++에서 2000 페이지 길이의 책을 읽는 것부터 시작했습니다 ... 그래서 나는 참을성이없는 방법 2이지만 참을성이 있습니다. If If C++ 템플릿을 사용하여 예를 들어 문자 대신 의상 구조로 간단한 클래스 쌍 작업을 할 수 있습니다.초보자 용 및 C++ 용 템플릿 : C++ 템플릿을 사용하여 문자를 사용하여 수업이 복장 구조와 함께 작동하도록하는 방법이 있습니까?

#include <iostream> 
#include <vector> 

// Boost 
#include <boost/thread.hpp> 

#ifndef _IGraphElementBase_h_ 
#define _IGraphElementBase_h_ 
#pragma once 

using namespace std ; 

class IGraphElementBase { 

public: 
    boost::thread GraphWorker; 
    mutable boost::mutex GraphItemMutex; 
    boost::condition_variable GraphItemMutexConditionVariable; 
    int SleepTime; 

    // Function for preparing class to work 
    virtual void Init(){ SetSleepTime(1);} 

    void SetSleepTime(int timeMS) 
    { 
     SleepTime = timeMS; 
    } 

    // Function for data update // word virtual makes it possible to overwrite it 
    virtual void updateData(){} 


    void StartThread() 
    { 
     GraphWorker = boost::thread(&IGraphElementBase::Call, this); 
    } 

    virtual void CleanAPI(){} 

    virtual void Clean() 
    { 
     GraphWorker.interrupt(); 
     GraphWorker.join(); 
     CleanAPI(); 

    } 
    virtual void CastData(){} 

    //Here is a main class thread function in infinite loop it calls for updateData function 
    void Call() 
    { 
     try 
     { 
      for(;;){ 
       boost::this_thread::sleep(boost::posix_time::milliseconds(SleepTime)); 
       boost::mutex::scoped_lock lock(GraphItemMutex); 
       boost::this_thread::interruption_point() ; 

       updateData(); 

       lock.unlock(); 
       CastData(); 
       GraphItemMutexConditionVariable.notify_one(); 
      } 
     } 
     catch (boost::thread_interrupted) 
     { 
      // Thread end 
     } 
    } 
}; 

#endif // _IGraphElementBase_h_ 

#include "IGraphElementBase.h" 

#ifndef _IGraphElement_h_ 
#define _IGraphElement_h_ 

using namespace std ; 

class IGraphElement : public IGraphElementBase{ 

    // We should define prototype of functions that will be subscribers to our data 
    typedef void FuncCharPtr(char*, int) ; 

public: 
    struct GetResultStructure 
    { 
     int length; 
     char* ptr; 
    }; 

    // initGet sets up a pointer holding a copy of pointer of data we want to return on Get() call 
    void InitGet(char * pointerToUseInGetOperations, int pointerToUseInGetOperationsSize) 
    { 
     pointerToGet = pointerToUseInGetOperations; 
     pointerToGetSize = pointerToUseInGetOperationsSize; 
    } 

    // Function for adding subscribers functions 
    void Add(FuncCharPtr* f) 
    { 
     FuncVec.push_back(f); 
    } 

    // Returns pointer to copy of current graphItem processed data 
    GetResultStructure Get() 
    { 
     boost::mutex::scoped_lock lock(GraphItemMutex); 
     char * dataCopy = new char[pointerToGetSize]; 
     memcpy (dataCopy,pointerToGet,pointerToGetSize); 
     lock.unlock(); 
     GraphItemMutexConditionVariable.notify_one(); 
     GetResultStructure result; 
     result.ptr = dataCopy; 
     result.length = pointerToGetSize; 
     return result; 
    } 

    void Clean() 
    { 
     GraphWorker.interrupt(); 
     GraphWorker.join(); 
     CleanAPI(); 
     //delete[] pointerToGet; 
     //pointerToGet = 0; 

    } 

    // Cast data to subscribers and clean up given pointer 
    void CastData(){ 
     for (size_t i = 0 ; i < FuncVec.size() ; i++){ 
      char * dataCopy = new char[pointerToGetSize]; 
      memcpy (dataCopy,pointerToGet,pointerToGetSize); 
      FuncVec[i] (dataCopy, pointerToGetSize) ;} 
    } 

    // Cast given data to subscribers and clean up given pointer 
    void CastData(char * data, int length){ 
     for(size_t i = 0 ; i < FuncVec.size(); i++){ 
      char* dataCopy = new char[length]; 
      memcpy(dataCopy, data, length); 
      FuncVec[i](dataCopy, length); 
     } 
    } 

private: 
    // Char pointer to hold a copy of pointer of data we want to return on Get() call 
    char* pointerToGet; 
    int pointerToGetSize; 

    // Vector to hold subscribed functions 
    vector<FuncCharPtr*> FuncVec ; 

}; 
#endif // _IGraphElement_h_ 

그래서 나를 위해 대부분의 기계류 무엇에 그 짧은 수업 :

- typedef void FuncCharPtr(char*, int) ; 
- vector<FuncCharPtr*> FuncVec ; 
- functions like void CastData(char * data, int length) 

그것은 어떻게 든 템플릿 내 수업 의상 구조와 작동하도록 사용하는 것이 possile 경우 나를 위해 기계류 정말주의입니다. 그렇다면 어떻게 할 수 있습니까?

+0

너무 많은 코드입니다. 좀 더 구체적으로 주시겠습니까? – Elalfer

+1

모호한 질문을 가진 긴 코드 목록을 던지면서도 표준 영어와 철자법을 사용하면 도움이 될 것입니다. – kirakun

답변

5

템플릿은 클래스의 매개 변수입니다. 즉, 패턴을 볼 수있는 경우

이 다른 유일한 것은 사용되는 유형입니다 ... 대신 같은

class myclass_int 
{ 
    int x; 
} 

class myclass_double 
{ 
    double x; 
} 

등으로 다른 클래스의 무리를 필요없이, 그래서, 우리는을 사용합니다 추상 형식이 클래스는 하나의 클래스하지만 전체 컬렉션을지지 않습니다

class myclass_T 
{ 
    T x; 
} 

, 장소 홀더의 일종으로 템플릿을했다. T를 int로 대체하면 첫 번째 클래스를 얻고 T를 두 번 사용하면 두 번째를 얻습니다.

그러나 myclass_T를 인스턴스화 할 때 실제로 T가 무엇인지 지정해야합니다 (int, double 등).

그래서 우리는

template <typename T> 
class myclass 
{ 
    T x; 
} 

으로이 매개 변수가있는 클래스를 정의하고 그것이 정말 무엇인지 이미 새로운 우리로 T를 사용합니다.

그 하나의 클래스는 사용 가능한 특정 유형의 모든 가능한 클래스를 나타냅니다 (처음 2 인스턴스를 제공함).

템플릿을 사용하면 이러한 클래스를 쉽게 정의 할 수 있습니다. 그보다 훨씬 더 많은 것이 있지만 그것이 유용하다는 이유의 기초입니다. 템플릿 기반 클래스를 생각하는 방법은 클래스가 아닌 "수퍼 클래스"입니다. 즉, 다른 표현을 수행 할 수있는 클래스입니다.

어려운 개념은 아니지만 oop에 대한 많은 경험이 없다면 실제로 유용한 이유를 알지 못하고 더욱 복잡한 것으로 생각할 수 있습니다. 그러나 일단 사용 된 유형에 따라 다른 많은 매우 유사한 클래스를 작성해야만하는 이유는 결국 그 클래스가 매우 유용한 이유입니다. 실제로는 훨씬 더 많은 작업을 수행 할 수 있기 때문에 실제로 매우 강력합니다.