2015-01-13 4 views
-1

저는 디자인 문제로 인해 문제가 있습니다. 파일 처리/드라이버 인터페이스를 나타내는이 템플릿 클래스가 있습니다. 그 클래스의 베어 본이 있습니다.C++ 템플릿 멤버 개체

---------------------------- FileDriver.h --------------- ------------

namespace DatabaseManager { 

template<class T> 
class FileDriver { 

FileDriver(const char *file_name) : file_name(file_name) {} 
public : 

T* fetch(size_t rec_size, long rec_num, long offset , bool write_enabled) { 

// fetch data from file 
} 

int insert(T *rec, size_t rec_size, long rec_num, long offset) { 

// insert data into file 

} 

inline int release(T *rec, size_t rec_size, int rec_num) { 
// close the file 

} 

}; 

} 

이 클래스는 I/O 작업이 필요한 시스템의 모든 클래스에서 사용됩니다. 하지만 템플릿 클래스로 그래서 나는 파일에 액세스해야 할 때마다이 클래스의 객체를 만들어야한다. 예를 들어 여기에 함수가이 클래스를 사용하는 방법이 있습니다.

---------------------- ParseSparseParticles.cpp ------------------ 

    #include "FileDriver.h" 

    bool ParseSparseParticles::openFile() throw(ParseSparseParticlesException) 
    { 

     // DatabaseManager::FileMetaInfo is a struct containing meta information about a file 
     DatabaseManager::FileMetaInfo *meta_info = nullptr; 
     DatabaseManager::SparseParticles *particle_data = nullptr; 

     DatabaseManager::FileDriver<DatabaseManager::FileMetaInfo> meta_hndlr(meta_file_name.str().c_str()); 
     meta_info = meta_hndlr.fetch(sizeof(DatabaseManager::FileMetaInfo), 1, static_cast<int>(DatabaseManager::file_map_pos::START), false); 

     if (meta_info) { 

     DatabaseManager::FileDriver<DatabaseManager::SparseParticles> data_hndlr(file_name.str().c_str()); 

     particle_data = data_hndlr.fetch(sizeof(DatabaseManager::SparseParticles), 
            meta_info->num_rec, static_cast<int>(DatabaseManager::file_map_pos::START), false); 

     if (particle_data) { 
      data_hndlr.release(particle_data, sizeof(DatabaseManager::SparseParticles), meta_info->num_rec); 
      meta_hndlr.release(meta_info, sizeof(DatabaseManager::FileMetaInfo), 1); 
      return true; 
     } else { 
      throw ParseSparseParticlesException("Cannot open Sparse Particles File"); 
     } 

     } else { 
     throw ParseSparseParticlesException("Cannot open Meta Info File"); 
     } 

    } 

그래서 모든 파일에 액세스해야 할 때마다 똑같은 단계를 따라야합니다. 메타 정보가 2. 데이터 파일 4. 메타 파일을

을 닫고이 언젠가 후 무심 도착 3. 닫기 악화가 코드를 복제 리드 실제 데이터 파일을 파일 1. 구조화되지 않은 코드 파일 조작은 시스템 전체에서 수행되므로 그래서 I/O 작업을 추상화 할 인터페이스를 만드는 것에 대해 생각하고있었습니다. 그리고하는 과정에서 그래서 난 인터페이스 클래스의 FileDriver 구성원 개체를 만들고 싶었 때 내가 너무

--------------------------- IOInterface.h --------------------------- 


    #include "FileDriver.h" 

    template<typename MetaFileType, typename FileType> 
    class IOInterface { 

    DatabaseManager::FileDriver<MetaFileType> meta_orb; // won't compile 

    DatabaseManager::FileDriver<FileType> data_orb; // won't compile 

    }; 

처럼 비틀 거렸다하지만 난 다른 템플릿 헤더에 템플릿 헤더를 포함하고있어 이것은 컴파일되지 않습니다. 그래서 누구든지이 문제를 해결하는 방법을 알려주실 수 있습니다. 클래스 개체가 살아있는 한 FileDriver 개체를 저장할 FileDriver 인터페이스처럼 작동하는 클래스를 만들 수 있습니까?

감사

UPDATE

컴파일하는 동안 내가지고있어 오류가 IOInterface의 생성자입니다. 코드보고에서

IOInterface::IOInterface(std::string data_dir, std::string file_prefix, int id) : 
    data_dir(data_dir), 
    file_prefix(file_prefix), 
    file_id(id) 
{} 

/var/local/PolymerizationSimulation/include/IOInterface.h:7: error: no matching function for call to 'DatabaseManager::FileDriver<DatabaseManager::MetaFileType>::FileDriver()' 

/var/local/PolymerizationSimulation/include/IOInterface.h:7: error: no matching function for call to 'DatabaseManager::FileDriver<DatabaseManager::FileType>::FileDriver()' 
+0

컴파일 오류가 무엇을 :

DatabaseManager::FileDriver<MetaFileType> meta_orb; // won't compile DatabaseManager::FileDriver<FileType> data_orb; // won't compile 

그래서 컴파일러는 FileDriver에 대한 추가, 어떻게 그 인스턴스를 만드는 아무 생각이 : 마지막으로이 클래스는 기본 생성자가 필요로 제공하지 않는 이유는 무엇입니까? "템플릿 헤더를 다른 템플릿 헤더에 포함시키는 것"이 ​​컴파일되지 않을 이유는 없습니다. –

+0

"다른 템플릿 헤더에 템플릿 헤더 포함". 거기에 아무런 문제가 없습니다. –

+1

* 실제 코드 *는 (a) FileDriver의 어떤 것도 public이 아니며 (b) IOInterface의 해당 객체 모두 초기화가 필요하기 때문에 엄청나게 도움이됩니다. FileDriver의 생성자가 실제로 공개 되었으면 매개 변수가 선택적이 아닙니다. 코드를 제거하려고하면 문제가 여전히 나타나고 스트립 다운으로 인해 크게 손상되지 않은 경우 도움이됩니다. – WhozCraig

답변

0

몇 가지 힌트 :

당신은 클래스 정의 후 세미콜론를 그리워 :

귀하의 예제에서 또한
}; 
^ 

, FileDriver이 클래스에서 DatabaseManager

에 있지 :

template<class T> 
    class FileDriver { 

모든 멤버는 private, 심지어 생성자이므로 액세스 할 수 없습니다.

FileDriver(){} 
+0

죄송합니다 코드를 붙여 넣을 때 세미 콜론을 넣지 않았습니다. FileDriver의 모든 메서드는 공개되어 있으며 공용 생성자가 있으므로 게시하는 동안 액세스 한정자가 누락되었습니다. – Maxx

+0

@Maxx : 우리의 시간을 낭비하지 말고 _ 최소한의 testcase_를 게시하십시오. –

+0

@LightnessRacesinOrbit 그럼 지금은 별도의 테스트를 준비 할 필요가 없습니다. 그게 내가 왜 그 문제를 설명하는지 그 함수'bool ParseSparseParticles :: openFile()'을 게시 한 이유입니다. 그리고 주된 문제는이 표현식 인'DatabaseManager :: FileDriver meta_orb;'로 IOInterface에서하고 싶었던 것처럼 템플릿 멤버 객체를 초기화하는 적절한 방법입니다. 하지만 슬프게도 컴파일되지 않았고, 템플릿 프로그래밍에 익숙하지 않았으므로 다소 어려웠습니다. 하지만 어쨌든 내가 어떻게 든이 문제를 해결할 수 있는지 알게 될 것입니다. – Maxx

관련 문제