ProgrammatieC++ ontwikkelaar

Leg het verschil uit tussen de sleutelwoorden 'explicit' en 'implicit' bij het declareren van constructors, en hoe hun toepassing invloed heeft op de initialisatie van objecten in C++.

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord

In C++ wordt een constructor die met één argument kan worden aangeroepen standaard beschouwd als implicit. Deze constructor kan worden gebruikt voor ** impliciete typeconversies**. Om dit te voorkomen, wordt het sleutelwoord explicit gebruikt.

  • explicit constructors verbieden impliciete conversies.

Het gebruik van explicit helpt onverwachte conversies te voorkomen die kunnen optreden, bijvoorbeeld wanneer een argument van een niet-overeenkomend type aan een functie wordt doorgegeven of bij het initialiseren van een variabele.

Voorbeeld:

struct Foo { explicit Foo(int x) { /* ... */ } }; Foo a = 10; // Fout, explicit verbiedt impliciete initialisatie Foo b(10); // Goed

Als explicit niet was gebruikt, zou de regel Foo a = 10; zijn toegestaan en zou dit kunnen leiden tot onverwachte bugs.

Vragend met een valstrik

Vraag: Kunnen alle constructors die met explicit zijn gedeclareerd niet worden aangeroepen bij initialisatie met = ?
Veelvoorkomend antwoord: Ja, explicit verbiedt elke initialisatie met =.
Juiste antwoord: explicit verbiedt alleen impliciete conversies. Met directe initialisatie (ClassName obj(param);) wordt de explicit constructor aangeroepen. Met kopie-inititalisatie (ClassName obj = param;) is dat niet het geval.

Voorbeeld:

struct A { explicit A(int) {} }; A x = 1; // Fout A y(1); // OK

Voorbeelden van echte fouten door onbekendheid met de nuances van het onderwerp


Verhaal: In een project was er een constructor geschreven zonder explicit, die initialisatie via types toestond, wat leidde tot ongewenste automatische conversies van functieargumenten. Dit leidde tot het ontstaan van verborgen fouten en bemoeilijkte het debuggen.



Verhaal: Een ontwikkelaar had geen explicit voor de containerconstructor geplaatst, en de standaardconstructor werd plotseling aangeroepen bij toewijzing of overdracht van andere types. Het resultaat - onjuiste logica voor het creëren van objecten en onvoorspelbaar gedrag.



Verhaal: Een onervaren programmeur verklaarde een explicit constructor, maar was verrast dat directe initialisatie met ronde haakjes werkte, denkend dat explicit ook dat blokkeerde. Dit leidde tot het niet gebruiken van handige veilige patronen en overbodige code in het project.