ProgrammatieC++ ingenieur

Leg uit hoe overload en standaardwaarden voor lidfuncties in C++ werken. Wat zijn de nuances van het gelijktijdig gebruik van overloaded functies en standaardwaarden?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

Functie-overloading (overloading) is een mechanisme om meerdere functies met dezelfde naam, maar met een verschillende handtekening (aantal of type parameters) te verklaren.

Standaardwaarden voor parameters kunnen worden opgegeven in de functieverklaring. Nuance: standaardwaarden worden alleen in aanmerking genomen bij het compileren van de aanroep en worden door de compiler ingevoegd, op basis van de zichtbare handtekening.

In klassen komt vaak de situatie voor:

class Printer { void print(int n, char c = '*') { /* ... */ } void print(const std::string& s) { /* ... */ } }; Printer p; p.print(5); // roept print(int n, char c = '*') aan, c = '*' p.print("Hi"); // roept print(const std::string&) aan

Nuances:

  • Het is niet goed om een functie tegelijkertijd te overladen en ze alleen te onderscheiden via standaardwaarden, dit leidt tot dubbelzinnigheid.
void foo(int x, int y = 10); void foo(int x); foo(1); // Fout: onduidelijk welke functie te aanroepen

Misleidende vraag.

Welke plaats is de enige waar een standaardwaarde voor een lidfunctie van een klasse mag worden opgegeven?

Antwoord: Een standaardwaarde voor een klassemethode mag worden opgegeven in de methodeverklaring binnen de klasse (of in de eerste declaratie buiten de klasse), maar het is niet toegestaan om het zowel in de klasse als in de implementatie op te geven. Anders ontstaat er een fout vanwege duplicaatdefinitie.

class X { void func(int x = 5); // Hier kan het }; void X::func(int x) { /* ... */ } // Maar hier niet!

Voorbeelden van echte fouten door gebrek aan kennis van de nuances van het onderwerp.


Verhaal 1

In bancaire software was er een compilatiefout: een deel van de overloaded functies met verschillende standaardwaarden verstoorde de eenduidige selectie, aanroepen waren dubbelzinnig tijdens het compileren — resultaat, het was niet mogelijk een release samen te stellen voor het corrigeren van handmatige aanpassingen.


Verhaal 2

Binnen het team was er een gebruik waarin alle standaardwaarden naar de implementatie werden verplaatst en niet naar de header van de klasse, maar voor sommige methoden van klassen leidde dit tot een discrepantie tussen de interface en de implementatie — verschillende TU's zagen verschillende functieparameters, wat leidde tot vreemde compilatie- en run-time fouten.


Verhaal 3

Bij het uitbreiden van een openbare bibliotheek werd per ongeluk een overload van de functie toegevoegd met dezelfde parameters, maar verschillende standaardwaarden. De compiler begon ambiguïteit te geven bij API-aanroepen, en gebruikers stuitten op verouderde aanroepen en gebroken binaire compatibiliteit.