泛型抽象类型c++

generic abstract type c++

本文关键字:c++ 类型 抽象类 抽象 泛型      更新时间:2023-10-16

我想在c++中定义一个泛型类,允许在任何数据上执行我的算法。问题是,这些数据可以是任何东西(例如,浮点向量、图形等)。在我的课上,有没有可能说被操纵的数据是T类型的,可以是任何东西?然后,我的类的用户将不得不实现我的类中与操作他的数据相关的一些方法(例如,根据他的数据,他定义如何对两个数据求和,等等…)

编辑:

那么,如何实例化类模板并调用其方法呢?当我这样做时,我有一个错误:

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

错误:请求"tst"中的成员"test",该成员属于非类类型"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()
{
    // ...
}

作为@Als注释,您完美地描述了类模板

你可以在http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fclass_templates.htm

是的,您可以这样做,只要您希望在类中使用的所有不同类型的数据都支持算法所需的操作。

如果您将模板方法用于所需的特定于类型的操作,则用户可以将这些方法专门用于需要默认实现以外的其他内容的输入类。

假设<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
}

只有在一个文件(例如.cpp)中写入时,这才有效。如果您正在处理具有多个文件(头文件和源文件)的大型项目,则必须避免使用模板,因为编译器可以在使用模板时查看和分析模板。这是一个巨大的问题,因为重新定义模板是一个经常出现的错误。