Wanneer treedt een Incomplete Type-fout op in C++

Kan iemand me vertellen wanneer een c++-compiler een “onvolledige typefout” geeft?

Opmerking: ik heb deze vraag met opzet een beetje opengelaten, zodat ik zelf fouten in mijn code kan opsporen.


Antwoord 1, autoriteit 100%

Dit gebeurt meestal wanneer de compiler een forward-declaratie heeft gezien, maar geen volledige definitie van dit type, terwijl het type ergens wordt gebruikt. Bijvoorbeeld:

class A;
class B { A a; };

De tweede regel zal een compilerfout veroorzaken en, afhankelijk van de compiler, een onvolledig type rapporteren (andere compilers geven een andere fout, maar de betekenis is hetzelfde).

Als je echter gewoon een pointer naar zo’n forward-declaratie gebruikt, zal er geen klacht naar voren komen, aangezien de grootte van een pointer naar een klasse altijd bekend is. Zoals dit:

class A;
class B {
   A *a;
   std::shared_ptr<A> aPtr;
};

Als je vraagt wat er mis kan zijn in een concrete applicatie of bibliotheek als deze fout zich voordoet: dat gebeurt meestal als er een header is opgenomen die de forward-declaratie bevat, maar de volledige definitie is nog niet gevonden. De oplossing ligt voor de hand: voeg ook de header toe die u toegang geeft tot het volledige type. Soms heb je ook gewoon geen of de verkeerde naamruimte voor een type en moet je die in plaats daarvan corrigeren.


Antwoord 2, autoriteit 11%

Dit gebeurt wanneer we een klasse/object of zijn methoden proberen te gebruiken en deze nog niet zijn gedefinieerd. Bijvoorbeeld

class A;
class B {
    class A obj;
}

of

class A;
class B {
    class A *obj;
    B() {   
           obj->some_method();
        }

Om dit op te lossen, moet A eerst worden gedefinieerd of moet de totale declaratie worden gegeven (best practice is om het in een headerbestand te doen) en alle methoden van beide klassen moeten later worden gedefinieerd (best practice is om het te doen in een ander bestand).

class A {
    //definition
}
class B {
class A obj;
}

Antwoord 3, autoriteit 5%

In mijn geval was dit te wijten aan een slechte kennis van sjablonen. Ik heb een klasse gedeclareerd tussen een sjabloondefinitie en de functie die aan die sjabloon was gekoppeld.

template<typename T>
class
{
  foo a;
  foo b;
};
function(T a,int b)
{
 . . . . .
}

En dit zorgde voor problemen omdat de sjabloondefinitie is gekoppeld aan de klasse, in dit geval komt er een fout in de parameterlijst van de functie dat T is not defineden ook dat incomplete type is not allowed. Als u een sjabloon voor meerdere entiteiten moet gebruiken, moet u deze verklaring opnieuw gebruiken voor de definitie van die entiteiten:

template<typename T>

Antwoord 4, autoriteit 5%

Dit gebeurt ook wanneer u forward-declaratie gebruikt met std::unique_ptr(bijvoorbeeld om het PIMPL-idioom te implementeren) in uw klas met een standaarddestructor, wat tot een dergelijk probleem leidt.

Het wordt hier goed uitgelegd: Declaratie doorsturen met unique_ptr?

Other episodes