Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Probleme de comprehension : constructeur de copie (templates?)

53 réponses
Avatar
Alex Paris
Bonjour =E0 tous !

Voil=E0 mon petit exemple que je compile en utilisant g++ (cygwin)


#include <iostream>

using namespace std;

template<class T>
class Matrix
{
public:
Matrix(int size);
Matrix(const Matrix<T> &copy);

~Matrix();

Matrix<T>& operator=3D(const Matrix<T>& matrix);

Matrix<T> operator+(const Matrix<T>& second);

private:
int _size;
};

template <class T>
Matrix<T>::Matrix(int size)
: _size(size)
{
cout << "--- Constructor called --- " << endl;
}

template <class T>
Matrix<T>::Matrix(const Matrix<T> &copy)
: _size(copy._size)
{
cout << "--- Copy constructor called --- " << endl;
}

template <class T>
Matrix<T>::~Matrix()
{
cout << "--- Destructor called --- " << endl;
}

template <class T>
Matrix<T>& Matrix<T>::operator=3D(const Matrix<T>& matrix)
{
cout << "--- Operator \"=3D\" called --- " << endl;
_size =3D matrix._size;
}

template <class T>
Matrix<T> Matrix<T>::operator+(const Matrix<T>& second)
{
cout << "--- Operator \"+\" called --- " << endl;
Matrix<T> result(_size);
return result;
}



int main()
{
cout << "Declaration m1" << endl;
Matrix<int> m1(2);
cout << "Declaration m1" << endl;
Matrix<int> m2(2);

cout << "Declaration mSum1" << endl;
Matrix<int> mSum1(2);
cout << "mSum1 =3D m1 + m2" << endl;
mSum1 =3D m1 + m2;

cout << "Declaration mSum2 =3D m1 + m2" << endl;
Matrix<int> mSum2 =3D m1 + m2;

cout << "Declaration mSum3" << endl;
Matrix<int> mSum3(2);
mSum3 =3D m1 + m2;

cout << "Declaration m4 =3D mSum3" << endl;
Matrix<int> m4 =3D mSum3;

int ret;
cin >> ret;

return ret;
}


Comme on voit bien dans le programme en bas la cr=E9ation est appell=E9e
plusieurs fois.

Et voil=E0 la sortie du programme :

$ ./a.exe
Declaration m1
--- Constructor called ---
Declaration m1
--- Constructor called ---
Declaration mSum1
--- Constructor called ---
mSum1 =3D m1 + m2
--- Operator "+" called ---
--- Constructor called ---
--- Operator "=3D" called ---
--- Destructor called ---
Declaration mSum2 =3D m1 + m2
--- Operator "+" called ---
--- Constructor called ---
Declaration mSum3
--- Constructor called ---
--- Operator "+" called ---
--- Constructor called ---
--- Operator "=3D" called ---
--- Destructor called ---
Declaration m4 =3D mSum3
--- Copy constructor called ---
0
--- Destructor called ---
--- Destructor called ---
--- Destructor called ---
--- Destructor called ---
--- Destructor called ---
--- Destructor called ---


Ce que m'int=E9resse le plus c'est pourquoi j'ai ces lignes l=E0 :
Declaration mSum2 =3D m1 + m2
--- Operator "+" called ---
--- Constructor called ---

Je ne vois pas l'operator=3D ni de constructeur de copie. Si je mets le
vrai code pour la classe matrix, le mSum2 est en effet la somme des 2,
l'objet est cr=E9=E9 et vit bien =E7a vie...

Quelqu'un saurait-il m'expliquer la suite des appels ici ? J'imagine
que la ligne
--- Constructor called ---
correspond =E0 la cr=E9ation de l'objet temporaire dans l'operator +. Mais
o=F9 est la trace de l'operator =3D ?



Merci d'avance
A+

10 réponses

2 3 4 5 6
Avatar
Fabien LE LEZ
On Wed, 08 Aug 2007 06:38:37 -0700, Alex Paris :

La personne n'est pas censé savoir quoi que ce soit sur la STL


Étre à un niveau suffisamment avancé pour écrire ses propres
templates, et ne pas connaître la base (i.e. la notion de tableau), ça
fait peur...

Avatar
Alex Paris
On 8 août, 14:11, "Christophe Lephay"
wrote:
De mon coté, je n'en serais pas surpris. Le C++ et le C++ enseigné par
certains professeur n'ont parfois que le nom en commun. J'ai déjà ren contré
des profs d'info enseignant le C++ qui n'avaient jamais entendu parlé de
vector (c'était il y a à peu pret 5 ans, les vector n'étaient donc pas une
nouveauté). Dans la foulée, les profs qui ne maitrisent pas leur suje t sont
souvent réfractaires aux notions qu'ils ne connaissent pas, impossible
qu'ils sont d'accepter l'idée qu'un de leur étudiants puisse connaitre
quelque chose qu'eux-mêmes ignorent.



C'est depuis quand l'utilisation de STL est obligatoire lorsqu'on
parle de C++ ?

Je suis d'accord que dans le cadre professionnel il est fortement
conseillé d'utiliser les librairies mais pour les exercices d'études
tu peux très bien te base sur la notion du langage même en état pur.

En ce qui concerne cout/cerr et I/O c'est une question de choix quoi
qu'il en soit tu es obligé de montrer tes résultat

Mais lorsqu'on te demande de FAIRE une classe template Matrix qui
gère ... (patati patata... regarde plus haut)... d'après moi il n'est
pas question de montrer tes connaissance en STL.

Tu pouvais sinon d'aller cherche les lib motif pour faire une belle
fenêtre, des ascenseurs, les couleurs : )))) etc. Envoyer les
resultats direct sur le mail de prof via un librairie SMTP etc etc.
Mais ce n'est pas le but c'est tout

Avatar
Alex Paris
On 8 août, 15:47, Fabien LE LEZ wrote:

Étre à un niveau suffisamment avancé pour écrire ses propres
templates, et ne pas connaître la base (i.e. la notion de tableau), ça
fait peur...


Et ben non, la notion de tableau est bien connue ! Il y a un pointeur
T** dans mon exemple

J'ai une impression qu'on parle pas de la même chose. Rappelez-vous du
bon vieux temps quand on faisait des exercices de toute sorte à
l'école sans utiliser les librairies. Non ? Jamais ? Mais alors...

Avatar
Christophe Lephay
"Michael DOUBEZ" a écrit dans le message de news:
46b9c32b$0$21534$
Mon propos etait qu'un simple vector est mieux qu'un vector de vector.


Je suis d'accord. Je t'avais mal compris :)

Avatar
Michael DOUBEZ
"Michael DOUBEZ" a écrit dans le message de news:
La méthode classique pour la représentation d'une matrice dense sans
autres caractéristiques (triangulaire, diagonale, creuse ...) est
d'utiliser un tableau unidimensionnel et d'utiliser operator()(int i, int
j){return (i*N+j);} pour acceder aux éléments.


Ta méthode classique est nickel à supposé que la taille des matrices soient
fixe, ce qui est peu probable si on écrit un opérateur d'affectation.


Je ne vois pas le problème. Je n'ai pas dit que les dimensions étaient
fixe. Si on peut se permettre une copie c'est très simple de toutes
façons et sinon:

template<typename T>
class Matrix
{
public:
Matrix(unsigned n,unsigned m,const T& default=T()):
n_(n),m_(m),data_(n*m,default)
{
}

T& operator()(int i, int j){return (i*m_+j);}
//... accessors

void resize(unsigned n,unsigned m)throw()
{
if(n*m>data_.size())
{ // resize now
}
if(m<m_)
{
//reorganize data_ to have lines of length m length - discard data
}
if(n*m<data_.size())
{//shorten data
}
if(m>m_)
{
//reorganize data_ to fit new line size
}
m_=m;
n_=n;
}

private:
unsigned n_;//!< number of lines
unsigned m_;//!< length of lines
vector<T> data_;
};



A moins que ce ne soit demander (ou que le prof demande l'utilisation de
POD comme un tableau de valeurs), l'operateur de recopie n'est pas
nécessaire car tout est géré par le compilateur. Et c'est bien de montrer
qu'on sait ça aussi.


L'opérateur de recopie n'est sans doute pas nécessaire si tu utilises un
conteneur standard, mais j'aurais plutôt l'a priori contraire en utilisant
ta méthode classique.


La methode classique dont je parle utilise un vector<>. Si les tailles
sont fixes, je pourrait utiliser un array<>.

Finalement, les opérateurs algébriques ont intérêt à être définis en
dehors de la classe.


Peut-être pour certains d'entre eux, mais tu parles de quel intérêt,
concrètement ?


Du point de vue du design principalement et en particulier pour être
cohérent plus tard si j'augmente le nombre d'opérateurs sur Matrix ou si
j'opère une spécialisation (avec une classe de matrice spéciale
Diagonal, Triangular,...).


Pour la plupart d'entre eux, je serais tenté de dire que c'est plutôt
indifférent, plus une question de style que de réel intéret.


Au delà du style, c'est quand même bien de garder l'interface minimale.
C'est vrai que dans le cas d'un projet d'école, ça ne porte pas à
conséquence.

Michael


Avatar
Christophe Lephay
"Alex Paris" a écrit dans le message de news:

Tu utilises STL en disant - voilà fastoche ! Tu n'as pas assisté aux
cours tu arrives à la fin du trimestre et dit que tu sais tout faire.
C'est vite vérifié... Faut pas etre idiot pour comprendre que c'est
pas toi qui as fait le programme


Ouais, sauf qu'on ne parle pas de fonctionnalités avancés mais des
structures de base. Les premiers cours d'un langage, ce sont généralement
les types de données et les tableaux. Un tableau, en c++ contemporain, c'est
un vector.

Au contraire si l'exercice est bien défini tu as exactement ce que tu
as à faire, tu le fais puisque c'est prescrit et voilà. Rien à
reprocher.


Ouais, sauf que c'est dur d'avoir un exercice bien défini lorsqu'il y a des
tas de façons différentes de le résoudre. En général, un exercice repose sur
quelque chose du programme qui a été vu. Sur ce point, les auteurs de ce
forum ne peuvent que spéculer. Certains pourront spéculer qu'un vector,
c'est la base, et qu'un étudiant l'a forcément vu, tandis que d'autres,
selon quelques a priori sur la qualité de l'enseignement du C++, penseront
facilement le contraire.

Avatar
Michel Decima
On 8 août, 12:14, Michel Decima wrote:

Et puisqu'on est dans un cadre scolaire, montrer qu'on connait ces
techniques devrait permettre d'obtenir une meilleure note...


ET NON, mais pas du tout !

Alors on peut trouver une classe toute faite sur le net et dire voilà
la matrice ! Pas ça le but de l'exercice.


Est-ce vraiment ce que j'ai proposé ?

La personne n'est pas censé savoir quoi que ce soit sur la STL, et
d'ailleurs ne sait pas grande chose en informatique en général


Ah. Alors si la personne est un peu moins bornée que l'examinateur
le suppose, genre elle a ouvert un bouquin a la bibliotheque, elle
est moins bien notée que celle qui n'a pas fait preuve de curiosité ?

Si l'examinateur ne veut pas voir certaines bibliotheques, il devrait
les interdire explicitement dans l'enoncé, ou alors limiter le champ
d'action des élèves a ce qui a été vu en cours.
De la meme maniere, si le cours porte sur la gestion de la memoire,
l'ecriture des constructeurs de copie et operateurs d'affectation,
le candidat devrait se douter que std::vector ne vas pas etre la
meilleure reponse.

Maintenant, si le candidat propose sa propre classe Vector<T> qui
gere la mémoire, avec Matrix<T> qui s'appuie dessus, et en justifiant
la decision comme il faut, et que ca ne va pas... ca montre surtout
les competences de l'examinateur.


Avatar
Michael DOUBEZ
On 8 août, 14:11, "Christophe Lephay"
wrote:
De mon coté, je n'en serais pas surpris. Le C++ et le C++ enseigné par
certains professeur n'ont parfois que le nom en commun. J'ai déjà rencontré
des profs d'info enseignant le C++ qui n'avaient jamais entendu parlé de
vector (c'était il y a à peu pret 5 ans, les vector n'étaient donc pas une
nouveauté). Dans la foulée, les profs qui ne maitrisent pas leur sujet sont
souvent réfractaires aux notions qu'ils ne connaissent pas, impossible
qu'ils sont d'accepter l'idée qu'un de leur étudiants puisse connaitre
quelque chose qu'eux-mêmes ignorent.



C'est depuis quand l'utilisation de STL est obligatoire lorsqu'on
parle de C++ ?


AMA, depuis que c'est dans le standard, la STL fait partie du langage.


Je suis d'accord que dans le cadre professionnel il est fortement
conseillé d'utiliser les librairies mais pour les exercices d'études
tu peux très bien te base sur la notion du langage même en état pur.


Parler de langage a l'état pur fait penser à un clivage langage de
programmation/langage machine. Un langage de programmation utilise des
sortes de librairies: des mécanismes comme les exceptions ou les vtables
dépendent du compilateur par exemple.

Michael


Avatar
Christophe Lephay
"Alex Paris" a écrit dans le message de news:

C'est depuis quand l'utilisation de STL est obligatoire lorsqu'on
parle de C++ ?


C'est vrai. Les classes n'ont rien d'obligatoire non plus, du reste.

Je suis d'accord que dans le cadre professionnel il est fortement
conseillé d'utiliser les librairies mais pour les exercices d'études
tu peux très bien te base sur la notion du langage même en état pur.


La SL fait partie du langage "à l'état pur".

Mais lorsqu'on te demande de FAIRE une classe template Matrix qui
gère ... (patati patata... regarde plus haut)... d'après moi il n'est
pas question de montrer tes connaissance en STL.


Il ne s'agit pas de "montrer" quoi que ce soit, il s'agit de faire un
programme ayant plus de chances d'être correct, avec le moins de bugs
possible.

En plus, il est important d'utiliser le plus possible les idiomes établis,
particulièrement dans un cursus éducatif.

Tu pouvais sinon d'aller cherche les lib motif pour faire une belle
fenêtre, des ascenseurs, les couleurs : )))) etc. Envoyer les
resultats direct sur le mail de prof via un librairie SMTP etc etc.
Mais ce n'est pas le but c'est tout


Bon, ça vire au troll. Je vais en rester là.

Avatar
Fabien LE LEZ
On Wed, 08 Aug 2007 06:43:45 -0700, Alex Paris :

Le but ce n'est pas d'obtenir le produit de matrices via un programme.
Mais l'exercice-même , n'est-ce pas ?


Exercice dont l'énoncé n'a pas été reproduit ici.
Si tu as besoin d'un tableau dans un programme, la méthode normale est
d'utiliser std::vector<>, sauf si ce n'est pas possible -- soit parce
que son interface ne convient pas, soit parce qu'il est explicitement
demandé de ne pas l'utiliser.

Si le but de l'exercice est d'implémenter soi-même, dans le détail, un
équivalent à std::vector<>, pourquoi pas.

Si le cours est basé sur l'idée qu'implémenter soi-même ce genre de
détails (i.e. des new[] partout) est normal/courant, alors c'est un
cours de C.

2 3 4 5 6