2017-06-11 6 views
0

私は現在、同じクラスを定義する2つの異なるヘッダを持っています。それらの間のどのような変更は、関数の実装と単一の変数です。テンプレート機能付きクロスプラットフォームクラス

header_linux.h

class Class 
{ 
private: 
    QStringList processesList; // Same variable 
    pid_t pid; // Different variable 

public: 
    void fillProcessesList() 
    { 
      // Different implementation 
    } 

    void isProcessRunning(QString name) 
    { 
      // Same implementation 
    } 

    template<typename T> 
    bool readMemory(unsigned long long address, T &destination) 
    { 
      // Different implementation 
    } 

header_win32.h

class Class 
{ 
private: 
    QStringList processesList; // Same variable 
    HANDLE handle; // Different variable 

public: 
    void fillProcessesList() 
    { 
      // Different implementation 
    } 

    void isProcessRunning(QString name) 
    { 
      // Same implementation 
    } 

    template<typename T> 
    bool readMemory(unsigned long long address, T &destination) 
    { 
      // Different implementation 
    } 

私は、単一のファイルに共通の変数と関数を持っていると思います。

私の考えは、OS-を実装する一般的な機能と、その後header_linux.cppheader_win32.cppを実装がheader.hクラスとそのメンバを定義しheader.cppを作成することでした具体的な機能

ただし、テンプレート関数はヘッダーファイルに実装する必要があります。

私は、プリプロセッサマクロを使ってオペレーティングシステムをチェックし、正しい実装を1つのヘッダーで使用することができますが、関数は多く、ボディは大きくなっています。

多くの研究の後、私はPIMPLイディオムを見つけましたが、実装は複雑に思えます。

良い方法がありますか?

+3

最初の数センテンスを読んだ後、「ピンプル」は私の頭に浮かんだ最初の考えでした。 –

+1

OS固有のものを**非**汎用関数にラップして、それとインターフェースする必要があります。私が知る限り、OSはテンプレート –

+1

***を実装していませんが、実装は複雑です。***間違ったソースを読んでいる必要があります。 PIMPLを使用すると、(少なくとも私にとっては)合併症はごくわずかです。私は1980年代初め以来プログラミングしてきましたが。 – drescherjm

答えて

1

cppファイルにテンプレート実装を書き込むことができます。テンプレート実装後に明示的なインスタンス化定義をcppファイルに書き込むだけで済みます。

http://en.cppreference.com/w/cpp/language/class_template#Explicit_instantiation

例:この例では

がheader.h

template <typename T> 
bool readMemory(unsigned long long address, T &destination); 

implementation.cpp

template <typename T> 
bool readMemory(unsigned long long address, T &destination) 
{ 
    // Implementation 
} 

// Explicit definitions 
template bool readMemory<std::string>(unsigned long long address, std::string &destination); 
template bool readMemory<int>(unsigned long long address, int &destination); 

readMemorystd::stringintのテンプレート引数を使用できます。したがって、テンプレートで使用されるすべてのtypenameの定義を記述する必要があります。そうしないと、リンカーエラーが発生します。これは明らかにソリューションのスケーラビリティを低下させますが、可能なテンプレート引数がいくつかしかない場合は、それを受け入れる必要があります。

+0

QtのPIMPLと明示的なインスタンス化を使用して私の問題を解決しましたが、これは現在2つしかありません。 –

関連する問題