2012-01-24 138 views
0

我想在C++中定義一個允許在任何數據上執行我的算法的泛型類。問題是這些數據可能是任何東西(例如浮點數,圖表等)。是否可以在我的課堂上說操縱的數據是T型的,可以是任何東西?然後我的類的用戶將必須實現相對我的課的一些方法來操縱他的數據(例如,取決於他的數據,他定義瞭如何做兩個數據的總和,等...)通用抽象類型C++

編輯:

那麼如何才能實例化類模板並調用它的方法?我有一個錯誤,當我做:

MyClass<int, int> tst(); 
tst.test(3, 4); // or even with tst.test<int, int>(3, 4); 

錯誤:請求部件在「TST」「測試」,其是非類類型的「MyClass的()」

類如果定義爲:

#include <iostream> 
#include <boost/graph/adjacency_list.hpp> 

using namespace std; 
using namespace boost; 

template<typename T1, typename T2> 
class MyClass 
{ 
    public: 
     MyClass(); 
     virtual ~MyClass(); 
     void test(T1 p, T2 s); 

    protected: 
     struct NodeData 
     { 
      T1 var1; 
      T2 var2; 
      int var3; 
     }; 

     struct EdgeData 
     { 
      int var; 
     }; 

     typedef adjacency_list<setS, setS, undirectedS, NodeData, EdgeData> Graph; 
     typedef typename Graph::vertex_descriptor NodeDataID; 
     typedef typename Graph::edge_descriptor EdgeDataID; 
     typedef typename graph_traits<Graph>::vertex_iterator VertexIterator; 

     Graph g; 
}; 

template<typename T1, typename T2> 
void MyClass<T1, T2>::test(T1 arg1, T2 arg2) 
{ 
    NodeDataID nId = add_vertex(g); 
    g[nId].anything = "but anything is not in struct NodeData !"; 
    g[nId].var1 = arg1; 
    g[nId].var2 = arg2; 
    g[nId].var3 = 55; 
} 

template<typename T1, typename T2> 
MyClass<T1, T2>::MyClass() 
{ 
    // ... 
} 

template<typename T1, typename T2> 
MyClass<T1, T2>::~MyClass() 
{ 
    // ... 
} 
+6

您需要一個Template類。 –

+0

@Als:A **類模板**,實際上。 (我也混合使用了很多。) –

+0

@DrewDormann Als 當我嘗試實例化類模板並調用其方法(僅用於測試時,出現錯誤)。看我的文章編輯。 – shn

回答

2

是的,你可以做到這一點,只要所有你希望在你的類支持使用你的算法需要操作的不同類型的數據。

如果您使用模板方法進行所需的特定於類型的操作,那麼您的用戶可以將它們專門用於其輸入類,這些輸入類需要默認實現以外的其他類。

1

獲得良好的腿關於這個問題在假設<T>必須保持洽:

我會建議有一個類,它發生在一個「操作處理程序」。傳入的操作處理程序將處理所有類型特定的操作。這是一個粗略的例子,我甚至不知道它是如何實現的,因爲我沒有在一段時間內實現這個功能,並且純粹從內存中編寫沒有編譯器的C++。這就是說,這應該顯示出基本的想法。

class CGenericOperationHandler<T>{ 

    public: 
    Sum(<T> left,<T> right); 

    Subtract(<T> left,<T> right); 

    Multiply(<T> left,<T> right); 

} 

class CFloatOperationHandler : CGenericOperationHandler<float>{ 

    public: 
    Sum(float left,float right){ return left + right; } 

    Subtract(float left,float right){ return left - right; } 

    Multiply(float left,float right){ return left * right; } 

} 


class CAlgoRunner<T>{ 

    CGenericOperationHandler<T>* myOpHandler; 

    CAlgoRunner(CGenericOperationHandler<T>* opHandler){ 
     myOpHandler = opHandler; 
    } 

    public: 
    <T> RunAlgo(<T> left, <T> right){ 
     return myOpHandler.Multiply(left, right); 
    } 

} 


main(){ 
    CFloatOperationHandler theOpHandler; 

    CAlgoRunner<float>* myRunner = new CAlgoRunner<float>(theOpHandler); 

    float result = myRunner.RunAlgo(6.0f, 1.5f); //result is (6 * 1.5) i.e. 9 
} 
0

這隻有在你寫入一個文件(例如.cpp)時纔有效。如果您正在處理包含多個文件(頭文件和源代碼)的大型項目,則必須避免使用模板,因爲編譯器可以在使用模板時查看和分析模板。這是一個巨大的問題,因爲重新定義模板往往是錯誤的。