Création d'une class Vecteur, questions et critiques
Le
Charly
Bonjour à tous,
pour les études, je dois réaliser une class Vecteur générique, voic=
i
ce que j'ai fait pour l'instant:
Vecteur.h http://pastebin.com/mSw1VpAL
Vecteur.cxx http://pastebin.com/2rVV3pGe
J'aimerai avec une (ou des) critiques sur mon code, ai-je pris des
mauvaises habitudes ? Y'a t'il des optimisation à faire ?
De plus, voici une question qui me pose bien des problèmes:
"Modifiez les traitements effectués dans votre programme principal
afin dafficher la valeur du
produit scalaire des vecteurs saisis (vecteur de « float » et de «
std ::string »). Normalement, vous devriez voir une erreur apparaître,
pourquoi ? Supprimez le traitement provoquant cette erreur. Que pouvez
vous déduire sur ce que fait le compilateur lorsque vous utilisez la
généricité ?"
Je comprend bien qu'il n'est pas possible du multiplier des float et
des string mais je ne vois pas comment corriger cette erreur. Comment
faire ?
Merci d'avance pour l'aide.
pour les études, je dois réaliser une class Vecteur générique, voic=
i
ce que j'ai fait pour l'instant:
Vecteur.h http://pastebin.com/mSw1VpAL
Vecteur.cxx http://pastebin.com/2rVV3pGe
J'aimerai avec une (ou des) critiques sur mon code, ai-je pris des
mauvaises habitudes ? Y'a t'il des optimisation à faire ?
De plus, voici une question qui me pose bien des problèmes:
"Modifiez les traitements effectués dans votre programme principal
afin dafficher la valeur du
produit scalaire des vecteurs saisis (vecteur de « float » et de «
std ::string »). Normalement, vous devriez voir une erreur apparaître,
pourquoi ? Supprimez le traitement provoquant cette erreur. Que pouvez
vous déduire sur ce que fait le compilateur lorsque vous utilisez la
généricité ?"
Je comprend bien qu'il n'est pas possible du multiplier des float et
des string mais je ne vois pas comment corriger cette erreur. Comment
faire ?
Merci d'avance pour l'aide.

Poser une question


Le "void" est en trop ici. Pour indiquer qu'il n'y a pas de
paramètres, une liste vide suffit :
unsigned int dimensions() const;
(En revanche, il est utile en C.)
Pas glop. Généralement, l'opérateur << ne doit pas être ami, mais doit
utiliser les fonctions membres publiques.
Par ailleurs, << ne modifie pas l'objet Vecteur, donc le paramètre
doit être une référence const, ou bien l'objet lui-même (passage par
valeur, qui est moins coûteux qu'il n'y paraît) :
template<class T>
std::ostream &operator<<(std::ostream &out, Vecteur<T> const& v)
{
unsigned int dim = v.dimensions();
out << "[";
for(unsigned int i=0; i<dim-1; ++i)
out << v[i] << ",";
out << v[dim-1] << "]";
return out;
}
Pour l'opérateur =, c'est pas mal, mais généralement on ajoute
carrément une fonction membre (publique) swap :
template<class T>
void Vecteur<T>::swap (Vecteur<T>& autre)
{
assert (autre.m_dim == m_dim);
std::swap (autre.m_values, m_values);
}
template<class T>
Vecteur<T> &Vecteur<T>::operator=(const Vecteur<T> &v)
{
Vecteur temp( v );
swap (temp);
return *this;
}
Gnii ?
"cout" n'a absolument rien à faire dans un opérateur >>.
Tout ça n'est pas cohérent. Pourquoi + est membre et pas * ?
En fait, aucun des deux ne devrait être membre.
Généralement, on met += comme opérateur membre, et + est une fonction
libre toute simple :
Vecteur<T> operator+ (const Vecteur<T> &v, const Vecteur<T> &w)
{
Vecteur<T> reponse (v);
reponse+= w;
return reponse;
}
Je n'ai pas l'énoncé sous les yeux, mais le design de la classe ne me
plaît pas.
Je préférerais un truc du style :
template <unsigned int dimension, class T>
class Vecteur
{
public:
Vecteur();
Vecteur <dimension, T> operator+= (Vecteur<dimension,T> const& v);
T &operator[](unsigned int i);
T operator[](unsigned int i) const;
private:
T m_values [dimension];
};
Le résultat est que "vecteur de float à 2 dimensions" et "vecteur de
float à 3 dimensions" sont deux types différents. Tenter d'ajouter un
vecteur 2D et un vecteur 3D donnera une erreur à la compilation.
Par ailleurs, même avec ton interface d'origine, tant que l'énoncé
n'indique rien, le moyen de stockage des données canonique est un
std::vector
template<class T>
class Vecteur
{
public:
Vecteur(unsigned int dim=3, const T &values=T());
Vecteur<T> &operator=(const Vecteur<T> &v);
Vecteur<T> operator+(const Vecteur<T> &v);
T &operator[](unsigned int i);
T const& operator[](unsigned int i) const;
unsigned int dimensions(void) const { return m_values.size(); }
private:
std::vector<T> m_values;
};
Enfin, note que "operator[] const" ne doit pas renvoyer une référence
non-const.
J'ai effectué les modifs, voici le résultat:
Vecteur.h : http://pastebin.com/JdxLyVvb
Vecteur.cxx : http://pastebin.com/Ti8HA0GF
En fait je n'ai pas le choix, la première parte de l'exercice
consistait (entre autre) à comprendre comment fonctionne l'allocation
dynamique, la 2ème partie (ou je suis rendu) consiste à rendre le tout
générique, sinon j'aurai effectivement utilisé des std::vector, bien
plus simples.
Concernant la question de sujet dans mon premier message, comment puis-
je faire pour multiplier des float et des std::vector sans que le
compilateur ne râle ?
merci.
Tel que je comprends l'énoncé, tu n'es pas censé pouvoir faire :
Mais tu dois expliquer pourquoi tu ne peux pas :
Et puisque ça ne fonctionne pas, tu dois virer la ligne en question
pour que le programme compile à nouveau :
Et enfin, tu dois en tirer une conclusion :