generic abstract type c++

956 views Asked by At

I want to define a generic class in c++ that allow to execute my algorithm on any data. The problem is that this data can be anything (e.g. a vector of floats, a graph, etc). Is it possible to say in my class that the manipulated data is of type T which can be anything ? Then the user of my class will have to implement some methods of my class relative to manipulating his data (e.g. depending on his data he define how to do a sum of two data, etc ...)

Edit:

How is it possible then to instantiate the class template and call its method ? I have an error when I do:

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

Error: request for member 'test' in 'tst', which is of non-class type 'MyClass()'

The class if defined as:

#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()
{
    // ...
}
4

There are 4 answers

0
Drew Dormann On BEST ANSWER

As @Als comments, you're perfectly describing a class template.

You can get a good leg up on the subject at http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fclass_templates.htm

0
Ian T. Small On

On the assumption that <T> must remain consistant:

I would recommend having a class which takes in an "operations handler". The operations handler passed in will handle all type specific operations. This is an INCREDIBLY rough example, and I'm not even sure how functional it is as I have not implemented this in some time and am writing c++ with no compiler purely from memory. That said, this should show the basic idea.

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
mwigdahl On

Yes, you can do this, as long as all the different types of data that you wish to use in your class support the operations your algorithm requires.

If you use template methods for the type-specific operations you need, your users can specialize these for their input classes that require something other than the default implementation.

0
Martin On

This works only if you write in one file (.cpp for example). If you are working on big projects with multiple files (header and source) you have to avoid templates because the compiler can see and analyze templates when they are used. It's a huge problem because redefinition of template is an often error.