Czy tworzenie konstruktora z wieloma argumentami explicit
ma jakiś (użyteczny) efekt?
Przykład:
class A {
public:
explicit A( int b, int c ); // does explicit have any (useful) effect?
};
c++
explicit-constructor
Peter G.
źródło
źródło
explicit
. Osobiście nie zawracałbym sobie głowy tworzeniem konstruktorów wieloskładnikowychexplicit
.Natknąłbyś się na to podczas inicjalizacji nawiasów klamrowych (na przykład w tablicach)
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; }
źródło
Głównym powodem są doskonałe odpowiedzi udzielone przez @StoryTeller i @Sneftel. Jednak IMHO, ma to sens (przynajmniej ja to robię), jako część przyszłego sprawdzania późniejszych zmian w kodzie. Rozważ swój przykład:
class A { public: explicit A( int b, int c ); };
Ten kod nie korzysta bezpośrednio z
explicit
.Jakiś czas później decydujesz się dodać domyślną wartość dla
c
, więc staje się ona następująca:class A { public: A( int b, int c=0 ); };
Robiąc to, koncentrujesz się na
c
parametrze - z perspektywy czasu powinien on mieć wartość domyślną. Niekoniecznie koncentrujesz się na tym, czyA
sam powinien być skonstruowany w sposób niejawny. Niestety, ta zmianaexplicit
znów ma znaczenie.Tak więc, aby pokazać
explicit
, że ctor jest , warto byłoby to zrobić podczas pierwszego pisania metody.źródło
explicit
, co było tam od zawsze, a pomoc techniczna będzie zalewana wezwaniami na temat tej zmiany i spędzać godziny na wyjaśnianiu, żeexplicit
to tylko hałas, a usuwanie go jest nieszkodliwe. Osobiście nie jestem dobry w przepowiadaniu przyszłości; Trudno zdecydować, co na tyle interfejs powinien wyglądać teraz .Oto moje pięć centów do tej dyskusji:
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; }
Jak łatwo zauważyć,
explicit
zapobiega używaniu listy inicjalizującej razem zbar
funkcją, ponieważ konstruktorstruct Bar
jest zadeklarowany jakoexplicit
.źródło