|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Junior Member
Iscritto dal: Mar 2008
Messaggi: 10
|
[c++]template di classe
Buonasera. Ho un piccolo problema da esporre. Ho questa classe:
Codice:
#ifndef ATTRIBUTOVALORE_H
#define ATTRIBUTOVALORE_H
#include "string.h"
using namespace std;
template <class T>
class AttributoValore{
public:
AttributoValore(T,string);
~AttributoValore();
bool setAttribute(string Attribute);
bool setValue(T Value);
T getValue();
string getAttribute();
private:
T value;
string attribute;
};
#endif
Codice:
#ifndef FATTO_H
#define FATTO_H
#include <list>
#include <string>
#include "attributovalore.h"
using namespace std;
class Fatto {
public:
Fatto(AttributoValore AV);
~Fatto();
bool setFactName(string name);
bool addAttVal(AttributoValore AV);
private:
string Name;
list<AttributoValore> Attributi;
};
#endif
|
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Quando usi la classe parametrica devi indicare al compilatore che tipo vuoi:
AttributoValore<int> AttributoValore<char> AttributoValore<MyClass> In questo modo il compilatore e' in grado di generare una classe completa usando rispettivamente int, char o MyClass al posto di T. Inoltre devi dichiarare tutti i metodi della classe template inline nel .hpp di modo che il compilatore li abbia disponibili al momento dell'instanziazione del template. Ti stai andando a cacciare in un grosso guaio con i template, occhio.
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
|
|
|
|
#3 |
|
Junior Member
Iscritto dal: Mar 2008
Messaggi: 10
|
quindi devo per forza già dire adesso quale sarà il tipo T, e non c'è un modo per dirlo successivamente?
comunque adesso ho modificato la classe cosi Codice:
#ifndef FATTO_H
#define FATTO_H
#include <list>
#include <string>
#include "attributovalore.h"
using namespace std;
typedef AttributoValore <int> AttributoV;
class Fatto {
public:
Fatto(AttributoV AV);
~Fatto();
bool setFactName(string name);
bool addAttVal(AttributoV AV);
private:
string Name;
list<AttributoV> Attributi;
};
#endif
Codice:
C:\Documents and Settings\Teddy\Documenti\Università\ICSE\Interprete\fatto.o(.text$_ZSt8_DestroyI15AttributoValoreIiEEvPT_[void std::_Destroy<AttributoValore<int> >(AttributoValore<int>*)]+0xd) In function `ZNSt10_List_baseI15AttributoValoreIiESaIS1_EE11_M_get_nodeEv': [Linker error] undefined reference to`AttributoValore<int>::~AttributoValore()' |
|
|
|
|
|
#4 | ||
|
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Quote:
Quote:
Esempio: Codice:
class MyFirstTemplate<typename T>
{
MyFirstTemplate()
{
// initialise class here
}
T Get(T& x) const
{
return x;
}
};
void main()
{
MyFirstTemplate<int> object_of_int; // instatiate MyFirstTemplate<int> here (well, a bit above)
assert(5 == object_of_int.Get(5)); // works!?
}
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA Ultima modifica di fek : 21-03-2008 alle 18:35. |
||
|
|
|
|
|
#5 |
|
Junior Member
Iscritto dal: Mar 2008
Messaggi: 10
|
Ho capito la questione dei template.
Per quanto riguarda il codice avevo già implementato i metodi: della prima classe Codice:
#include <iostream>
#include "attributovalore.h"
#include "string.h"
using namespace std;
template <class T>
AttributoValore<T>::AttributoValore(T valore, string attributo)
{
value=valore;
attribute=attributo;
}
template <class T>
AttributoValore<T>::~AttributoValore(){
cout<<"Coppia attributo-valore eliminata\n";
}
template <class T>
bool AttributoValore<T>::setAttribute(string Attribute)
{
attribute=Attribute;
if (attribute=="")
return false;
else
return true;
}
template <class T>
bool AttributoValore<T>::setValue(T Value)
{
value=Value;
if (value=="")
return false;
else
return true;
}
Codice:
#include "fatto.h"
#include <string>
#include <list>
#include <iostream>
#include "attributovalore.h"
using namespace std;
Fatto::Fatto(AttributoV AV){
Attributi.push_front(AV);
}
Fatto::~Fatto(){
cout<<"Fatto eliminato\n";
}
bool Fatto::addAttVal(AttributoV AV)
{
Attributi.push_front(AV);
if(Attributi.empty())
return true;
else
return false;
}
bool Fatto::setFactName(string name)
{
Name=name;
if(Name=="")
return false;
else
return true;
}
|
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
No, il problema e' che devi implementare i metodi inline come ho fatto io nel mio esempio. Il compilatore deve avere l'intera definizione della classe e dei suoi metodi in ogni unita' di traslazione che istanzia un template. Tante parole difficili per dire: definisci i metodi della classe template inline nel file .h, includilo dove usi la classe template, e funzionera' tutto.
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
|
|
|
|
#7 | |
|
Junior Member
Iscritto dal: Mar 2008
Messaggi: 10
|
Quote:
|
|
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Sì...questo perché le classi relative ai vari tipi di dati vengono generate in fase di compilazione.
|
|
|
|
|
|
#9 | |
|
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Quote:
Il processo si chiama istanziazione di un template: ogni volta che indichi esplicitamente i tipi associati ad una classe template, il compilatore crea letteralmente il codice di una nuova classe in quel punto (un po' prima in realta') e relativi metodi, sostituendo letteralmente ai tipi parametrici i tipi reali che hai indicato. Per fare questo ha bisogno di tutte le informazioni della classe template, quindi di tutte le dichiarazioni e tutti i metodi implementati.
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 18:04.




















