78 votes

Constructeur explicite prenant plusieurs arguments

Créer un constructeur ayant plusieurs arguments explicit a-t-il un effet (utile)?

Exemple:

 class A {
    public:
        explicit A( int b, int c ); // does explicit have any (useful) effect?
};
 

106voto

Sneftel Points 10929

Jusqu'en C ++ 11, aucune raison d'utiliser explicit sur un constructeur multi-argument.

Cela change dans C ++ 11, à cause des listes d'initialisation. Fondamentalement, l'initialisation de copie (mais pas l'initialisation directe) avec une liste d'initialiseurs nécessite que le constructeur ne soit pas marqué explicit .

Exemple:

 struct Foo { Foo(int, int); };
struct Bar { explicit Bar(int, int); };

Foo f1(1, 1); // ok
Foo f2 {1, 1}; // ok
Foo f3 = {1, 1}; // ok

Bar b1(1, 1); // ok
Bar b2 {1, 1}; // ok
Bar b3 = {1, 1}; // NOT OKAY
 

28voto

StoryTeller Points 6139

Vous tomberiez dessus pour l'initialisation de l'accolade (dans les tableaux, par exemple)

 struct A {
        explicit A( int b, int c ) {}
};

struct B {
         B( int b, int c ) {}
};

int main() {
    B b[] = {{1,2}, {3,5}}; // OK

    A a1[] = {A{1,2}, A{3,4}}; // OK

    A a2[] = {{1,2}, {3,4}}; // Error

    return 0;
}
 

23voto

Ami Tavory Points 24416

Les excellentes réponses par @Conteur et @Sneftel sont la principale raison. Cependant, à mon humble avis, cela a un sens (au moins je le fais), dans le cadre de la vérification future des modifications ultérieures du code. Considérez votre exemple:

class A {
    public:
        explicit A( int b, int c ); 
};

Ce code n'est pas directement bénéficier de l' explicit.

Quelques temps plus tard, vous décidez d'ajouter une valeur par défaut pour c, de sorte qu'il devient:

class A {
    public:
        A( int b, int c=0 ); 
};

Lorsque vous faites cela, vous êtes en se concentrant sur l' c paramètre - en rétrospective, il aurait une valeur par défaut. Vous n'êtes pas nécessairement l'accent sur l'opportunité A lui-même devrait être implicitement construit. Malheureusement, ce changement, explicit pertinentes de nouveau.

Alors, afin de faire comprendre qu'un ctor est - explicit, il pourrait payer pour le faire lors de la première écriture de la méthode.

6voto

Edgar Rokyan Points 1335

Voici mes cinq cents à cette discussion:

 struct Foo {
    Foo(int, double) {}
};

struct Bar {
    explicit Bar(int, double) {}
};

void foo(const Foo&) {}
void bar(const Bar&) {}

int main(int argc, char * argv[]) {
    foo({ 42, 42.42 }); // valid
    bar({ 42, 42.42 }); // invalid
    return 0;
}
 

Comme vous pouvez facilement le constater, explicit empêche l'utilisation de la liste d'initialisation avec les fonctions bar , car le constructeur de struct Bar est déclaré comme explicit .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X