Domanda

Voglio definire una classe generica in C ++ che consente di eseguire il mio algoritmo su qualsiasi dati. Il problema è che questi dati possono essere qualsiasi cosa (ad esempio un vettore di galleggianti, un grafico, ecc.). È possibile dire nella mia classe che i dati manipolati sono di tipo T che può essere qualcosa? Quindi l'utente della mia classe dovrà implementare alcuni metodi della mia classe rispetto alla manipolazione dei suoi dati (ad esempio, a seconda dei suoi dati, definisce come fare una somma di due dati, ecc ...)

Modificare:

Come è possibile quindi istanziare il modello di classe e chiamare il suo metodo? Ho un errore quando lo faccio:

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

Errore: richiesta per il membro "test" in "TST", che è di tipo non di classe 'myclass ()'

La classe se definita come:

#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()
{
    // ...
}
È stato utile?

Soluzione

Come commenta @als, stai descrivendo perfettamente un modello di classe.

Puoi ottenere una buona gamba sull'argomento a http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2fcom.ibm.xlcpp8l.doc%2fLanguage%2fref%2fclass_templates.htm

Altri suggerimenti

Sì, puoi farlo, purché tutti i diversi tipi di dati che desideri utilizzare nella tua classe supportano le operazioni richieste dall'algoritmo.

Se si utilizzano metodi modello per le operazioni specifiche del tipo, i tuoi utenti possono specializzarli per le loro classi di input che richiedono qualcosa di diverso dall'implementazione predefinita.

Sull'ipotesi <T> deve rimanere coerente:

Consiglierei di avere una lezione che assume un "gestore operativo". Il gestore delle operazioni trasmesso gestirà tutte le operazioni specifiche del tipo. Questo è un esempio incredibilmente approssimativo, e non sono nemmeno sicuro di quanto sia funzionale in quanto non lo implesso da un po 'di tempo e sto scrivendo C ++ senza il compilatore puramente dalla memoria. Detto questo, questo dovrebbe mostrare l'idea di base.

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
}

Funziona solo se si scrive in un file (.cpp per esempio). Se stai lavorando a grandi progetti con più file (intestazione e fonte) devi evitare i modelli perché il compilatore può vedere e analizzare i modelli quando vengono utilizzati. È un grosso problema perché la ridefinizione del modello è spesso un errore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top