2012-01-24 139 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)时才有效。如果您正在处理包含多个文件(头文件和源代码)的大型项目,则必须避免使用模板,因为编译器可以在使用模板时查看和分析模板。这是一个巨大的问题,因为重新定义模板往往是错误的。