struct A
{
A(const A& arg) : data(arg.data)
{
do_something_special();
}
// by writing copy constructor, we suppress the generation of
// implicit default constructor A::A()
int data;
};
void foo1()
{
A a; // does not work, since there's no default constructor
}
Disons que notre constructeur par défaut ne fait rien de spécial et est (plus ou moins) égale au compilateur a généré un. Nous pouvons le réparer soit par écrit notre propre constructeur par défaut (qui peut être fastidieux si notre classe a beaucoup de membres non statiques), ou en utilisant la syntaxe = default
:
struct A
{
A() = default;
A(const A& arg) : data(arg.data)
{
do_something_special();
}
int data;
};
Suppression des fonctions est utile lorsque nous vouloir interdire l'utilisation de surcharges spécifiques ou de spécialisations de modèles, ou simplement interdire la copie (ou le déplacement) d'objets.
void foo(char c) {}
void foo(int i) = delete; // do not allow implicit int -> char conversion
Lorsque vous voulez interdire la copie (à savoir des objets de fil), de la manière habituelle idiomatiques est de déclarer constructeur de copie privée sans mise en œuvre (oui, ou utiliser :: noncopyable boost). Bien que cela fonctionne pour la plupart des cas, vous pouvez parfois rencontrer des erreurs de liens obscurs. Tenir compte:
struct A
{
A() = default;
friend void foo();
private:
A(const A&);
};
void foo()
{
A a;
A b(a); // results in linker error in gcc
}
Faire A(const A&)
supprimé, nous évitons les erreurs de l'éditeur de liens potentiels et faire notre intention (interdire la copie) très claire.
@Christian: Si nous avions simplement 'struct S {S (int) {}},', 'la présence de S (int)' serait supprime le constructeur par défaut implicitement déclaré. –
Les règles pour POD ont été assouplies en C++ 0x/11, donc votre deuxième exemple serait également un POD en C++ 0x/11. Vous pouvez également utiliser les nouveaux traits :: is_pod pour vous vérifier avec un assertion statique par exemple. –
David
@David: Les règles pour POD ont en effet été assouplies, mais le second 'S' n'est toujours pas POD. Une structure POD doit être une classe triviale. Une classe triviale doit avoir un constructeur par défaut trivial. Un constructeur par défaut fourni par l'utilisateur n'est pas trivial. Le deuxième 'S' a un constructeur par défaut fourni par l'utilisateur et n'est donc pas POD. –