Default member initializer (standaard lidinitialisator) is een C++11 constructie die het mogelijk maakt om standaardwaarden direct bij de verklaring van de leden van de klasse te declareren. Deze mogelijkheid wordt vaak verward met andere manieren van initialisatie van gegevens.
Vroeg C++ stond niet toe om leden direct bij de verklaring te initialiseren; waarden werden alleen in de constructor toegewezen (in het lichaam of initialisatie lijst). De introductie van default member initializers (C++11) heeft de leesbaarheid verbeterd en het risico op fouten bij ongedefinieerde initialisatie verlaagd.
Als velden niet expliciet zijn geïnitialiseerd, bevatten ze "rommel" (ongedefinieerde) waarden. Toewijzing binnen de constructor is minder efficiënt in vergelijking met de initialisatie lijst, en het negeren van default member initializers bemoeilijkt de uitbreiding van klassen en het creëren van nieuwe constructors.
Gebruik default member initializers voor eenvoudige waarden, en voor complexe gevallen (vooral als een afhankelijke of niet-standaard waarde nodig is) de initialisatie lijsten van de constructor.
Voorbeeldcode:
class Widget { int x = 42; // default member initializer std::string name = "default"; // default member initializer public: Widget() = default; // x=42, name="default" Widget(int xx) : x(xx), name("new") {}// x=xx, name="new" };
Belangrijke kenmerken:
Zal default member initializer toegepast worden als het lid geïnitialiseerd is binnen het lichaam van de constructor, maar niet in de initialisatie lijst?
Antwoord:
Nee. Als het niet is opgegeven in de initialisatie lijst, wordt de variabele eerst geïnitieerd met de standaardwaarde (default member initializer), en daarna vindt de toewijzing in het lichaam van de constructor plaats, wat minder efficiënt is.
Wat is de volgorde van initialisatie van leden van een klasse met default member initializers bij overerving?
Antwoord:
Eerst worden de leden van de basis klasse geïnitialiseerd, vervolgens die van de afgeleide klasse; voor elk lid met default member initializer wordt eerst de initialisatie lijst van de constructor gebruikt, als deze is opgegeven, daarna de default member initializer, anders blijft hij niet-geïnitialiseerd (voor POD). Er vindt geen "dubbele initialisatie" plaats.
Kan default member initializer toegepast worden op static-leden van de klasse?
Antwoord:
Nee, static-leden kunnen niet worden geïnitialiseerd via default member initializer. Ze moeten buiten de klasse of met inline static in C++17 worden geïnitialiseerd.
Voorbeeld:
struct S { static int a = 5; // Fout! };
Een klasse met een dynamische string die vergeten is bij initiëren in verschillende constructors. Later bij toegang — ongedefinieerd gedrag.
Voordelen:
Nadelen:
Alle velden hebben default member initializers. Extra constructors initialiseren indien nodig expliciet de relevante leden via de initialisatie lijst.
Voordelen:
Nadelen: