Geschiedenis van de vraag
Statische leden van klassen zijn geïntroduceerd in C++ om een waarde of functie op te slaan die voor alle objecten gemeenschappelijk is, zonder dat deze aan een specifiek object van de klasse is gekoppeld. Dit is handig voor het opslaan van bijvoorbeeld tellers, objectfabrieken of hulpfuncties.
Probleem
Een van de moeilijkheden is altijd het bereik en het moment van initialisatie van dergelijke leden, vooral als er veel bronbestanden in de applicatie zijn. Onjuiste definitie van een static-lid leidt tot koppelingsfouten (linker errors).
Oplossing
In C++ worden static-leden gedeclareerd in de definitie van de klasse, maar de initialisatie (voor variabelen) moet apart in de cpp-bestand plaatsvinden (tot C++17). C++17 staat initialisatie direct binnen de declaratie toe, als het constexpr is.
Voorbeeldcode:
class MyClass { public: static int counter; static void increment() { ++counter; } }; int MyClass::counter = 0; // initialisatie is VERPLICHT buiten de klasse
Belangrijkste kenmerken:
Wat gebeurt er als je het static-lid niet in het cpp-bestand definieert?
Je krijgt een koppelingsfout (linker error), omdat de statische variabele gedeclareerd maar niet gedefinieerd is. Uitzondering is als static const int direct binnen de klasse is geïnitialiseerd voor een constexpr-waarde.
// .h class A { public: static int x; }; // .cpp // int A::x = 0; // als dit is gecommentarieerd - er zal een fout zijn
Kun je een niet-statische functie aanroepen vanuit een statische?
Nee. Een statische functie heeft geen toegang tot de this-pointer en niet-statische leden direct. Toegang is vereist via een specifiek object.
class B { int data; static void foo() { // data = 3; // fout } };
Zijn statische variabelen gemeenschappelijk voor alle instanties?
Ja, binnen één uitvoerbaar bestand en proces — dezelfde waarde voor alle instanties.
In het team is vergeten het static-lid in het cpp-bestand te definiëren, het project bouwt af en toe met een fout, en soms, bij het gebruik van inline-initialisatie (niet in alle compilers), verschijnt er een "mysterieuze" runtime-fout.
Voordelen:
Nadelen:
In het bedrijf is het beleid om: statische leden altijd in cpp-bestanden per klasse te definiëren. Voor thread-safety worden std::mutex of atomische operaties gebruikt.
Voordelen:
Nadelen: