
Envoyé par
foetus
Oui c'est la technique C++11 pour manipuler les temporaires
Mais a 2-3 subtilités cela revient à ce que j'ai dit

: à créer une autre méthode (donc ici
swap) et l'appeler des constructeurs et des opérateurs
Pas du tout, cela existait bien avant C++11.
Même si « Code < C++11 à l'arrache non testé », ton code est "archi faux".

Envoyé par
foetus
1 2 3 4
| protected:
std::vector<int> vec;
}; |
Par convention (pas du tout obligatoire), j'utiliserais m_vector au lieu de vec.
Pourquoi mettre cette donnée membre en protected ?
1 2
| private:
std::vector<int> m_vector; |
Et je mettrais le constructeur par défaut, qui a du sens (à partir de là tout est public) :
C++11
C++03
A() : m_vector() { } // A() { } devrait suffire

Envoyé par
foetus
1 2 3
| A(std::vector<int> init_vec) {
swap(init_vec);
}; |
La liste d'initialisation suffit amplement.
A(std::vector<int> const & vector) : m_vector(vector) { }

Envoyé par
foetus
1 2 3 4 5
| A(A& init_a) {
std::vector<int> copy_vec(init_a.vec);
swap(copy_vec);
}; |
Le constructeur de copie est généré automatiquement par le compilateur et fait la bonne chose, pas besoin de l'écrire ; mais si on devait le faire, ça serait :
A(A const & a) : m_vector(a.m_vector) { }
Là aussi, la liste d'initialisation suffit amplement, en plus si tu comptes utiliser l'idiome copy & swap, utiliser swap dans le constructeur par copie, ferait une boucle infinie (opérateur d'affectation qui appelle le constructeur par copie, qui appelle swap, qui appelle le constructeur par copie, ...)

Envoyé par
foetus
1 2 3 4 5 6 7
| A(int x, int y){
std::vector<int> new_vec(2);
new_vec[0] = x;
new_vec[1] = y;
swap(new_vec)
}; |
C++11
A(int const x, int const y) : m_vector({ x, y }) { }
C++03 (on pourrait faire une fonction qui prend deux entiers et retourne un vecteur avec ces deux entiers pour faire "comme en C++11")
A(int const x, int const y) : m_vector(2) { m_vector[0] = x; m_vector[1] = y; }

Envoyé par
foetus
1 2 3 4 5 6
| // Parameter: neither pointer nor reference
A& operator=(A other_a) {
swap(other_a.vec);
return *this;
}; |
L'opérateur d'affectation est généré automatiquement par le compilateur et fait la bonne chose, pas besoin de l'écrire ; mais si on devait le faire, ça serait :
A & operator =(A const & a) { m_vector = a.vector; return *this; }
Si on a une classe un peu plus compliquée, on peut utiliser l'idiome copy & swap
A & operator =(A const & a) { A tmp(a); std::swap(*this, tmp); return *this; }
La fonction template std::swap de la bibliothèque standard fait la bonne chose, si ce n'est pas le cas, on la spécialise. Voici une proposition :
On écrit la fonction membre.
1 2 3 4 5
| void swap(A & a)
{
using std::swap; // Pas nécessaire ici, mais c'est une bonne pratique (merci Flob90)
swap(m_vector, a.m_vector);
} |
Et voila la spécialisation (c'est une fonction libre).
1 2 3 4 5
| namespace std
{
template <>
void swap(A & a, A & b) { a.swap(b); }
} |
Et pour :

Envoyé par
foetus
1 2 3 4
| // Parameter: reference
void swap(std::vector<int>& other_vec) {
vec.swap(other_vec);
}; |
std::vector<int> n'a pas de fonction membre swap(). Voir ma proposition au dessus.
En fait si -_- (merci foetus).
Partager