C ++ Klassen-Forward-Deklaration

8

Wenn ich versuche, diesen Code zu kompilieren, bekomme ich:

%Vor%

ein Teil meines Codes:

%Vor%

Ich weiß wirklich nicht, was zu tun ist, ich suchte nach der Lösung, aber ich konnte nichts finden, das meinem Problem ähnlich ist ... Wirklich habe ich mehr Klassen mit Elternteil "Fliese" und es war in Ordnung vorher ... Danke für jede Hilfe.

BEARBEITEN:

Ich habe beschlossen, alle zurückgegebenen Typen in Zeiger zu ändern, um Speicherlecks zu vermeiden, aber jetzt habe ich:

%Vor%

Es ist nur in der Basisklasse, alles andere ist in Ordnung ... Jede Funktion in der Kachelklasse, die return * tile hat diesen Fehler ...

Irgendein Code:

%Vor%     
noisy cat 02.02.2012, 20:10
quelle

9 Antworten

11

Damit new T kompiliert werden kann, muss T ein vollständiger Typ sein. In Ihrem Fall, wenn Sie in der Definition von new tile_tree_apple tile_tree::tick sagen, ist tile_tree_apple unvollständig (es wurde vorwärts deklariert, aber seine Definition ist später in Ihrer Datei). Versuchen Sie, die Inline-Definitionen Ihrer Funktionen in eine separate Quelldatei zu verschieben oder verschieben Sie sie zumindest nach den Klassendefinitionen.

Etwas wie:

%Vor%

Wenn Sie Ihren Code auf diese Weise schreiben, beziehen sich alle Verweise auf A und B in diesen Methoden garantiert auf vollständige Typen, da keine weiteren Referenzen mehr vorhanden sind!

    
Armen Tsirunyan 02.02.2012, 20:13
quelle
16

Verwenden Sie nach Möglichkeit die Vorwärtsdeklaration.

Angenommen, Sie möchten eine neue Klasse B definieren, die Objekte der Klasse A verwendet.

  1. B verwendet nur Referenzen oder Zeiger auf A . Verwenden Sie die Forward-Deklaration, dann müssen Sie <A.h> nicht einschließen. Dies wiederum wird die Zusammenstellung ein wenig beschleunigen.

    %Vor%
  2. B leitet von A oder B explizit (oder implizit) ab Objekte der Klasse A . Sie müssen dann <A.h>

    einbeziehen %Vor%
kumaran 07.11.2012 10:56
quelle
5

Die Vorwärtsdeklaration ist ein " unvollständiger Typ ", das einzige, was Sie mit einem solchen Typ machen können, ist ein -Zeiger instanziieren oder auf eine Funktion verweisen Deklaration (dh und Argument oder Rückgabetyp in einem Funktionsprototyp). In Zeile 52 in Ihrem Code versuchen Sie, ein -Objekt zu instanziieren.

An diesem Punkt hat der Compiler weder Kenntnis von der Größe des Objekts noch von seinem Konstruktor, daher kann ein Objekt nicht instanziiert werden.

    
Clifford 02.02.2012 20:15
quelle
5

Ich hatte das:

%Vor%

...

Habe die gleiche Trauer wie in der ursprünglichen Frage. Wird nur durch Verschieben der Definition von paulzSprite nach nach von spriteFrame gelöst. Sollte der Compiler nicht schlauer sein als dies (VC ++, VS 11 Beta)?

Und ich stimme von ganzem Herzen mit Cliffords Bemerkung überein: "Zeiger verursachen keine Speicherlecks, schlechte Codierung verursacht Speicherlecks". IMHO dies gilt für viele andere neue "Smart Coding" -Features, die kein Ersatz für das, was Sie eigentlich den Computer fragen, werden soll.

    
Paul Pignon 09.12.2012 23:36
quelle
4

Das Problem ist, dass tick() die Definition von tile_tree_apple kennen muss, aber alles, was es hat, ist eine Vorwärtsdeklaration davon. Sie sollten die Deklarationen und Definitionen wie folgt trennen:

tile_tree.h

%Vor%

tile_tree.cpp :

%Vor%

Außer haben Sie ein großes Problem: Sie ordnen Speicher zu (mit new ), kopieren dann das zugewiesene Objekt und geben die Kopie zurück. Dies wird als Speicherverlust bezeichnet, da es für Ihr Programm keine Möglichkeit gibt, den von ihm verwendeten Speicher freizugeben. Nicht nur das, sondern du kopierst ein tile_tree in ein tile , das die Informationen verwirft, die ein tile_tree von einem tile unterscheiden; Dies wird slicing genannt.

Sie möchten einen Zeiger auf ein neues tile zurückgeben und sicherstellen, dass Sie delete irgendwann aufrufen, um den Speicher freizugeben:

%Vor%

Noch besser wäre es, einen intelligenten Zeiger zurückzugeben, der die Speicherverwaltung für Sie übernimmt:

%Vor%     
Jon Purdy 02.02.2012 20:18
quelle
3

class tile_tree_apple sollte in einer separaten .h-Datei definiert werden.

%Vor%

Eine andere Sache: Eine Kachel und keine Kachelreferenz zurückzugeben ist keine gute Idee, es sei denn, eine Kachel ist ein primitiver oder sehr "kleiner" Typ.

    
vulkanino 02.02.2012 20:17
quelle
0

Um etwas anderes als einen Zeiger auf ein Objekt zu deklarieren, benötigen Sie die vollständige Definition.

Die beste Lösung besteht darin, die Implementierung in eine separate Datei zu verschieben.

Wenn Sie dies in einer Kopfzeile beibehalten müssen, verschieben Sie die Definition nach beiden Deklarationen:

%Vor%

Wichtig

Sie haben Speicherlecks:

%Vor%

erstellt ein Objekt auf dem Heap, das Sie anschließend nicht zerstören können, es sei denn, Sie führen ein hässliches Hacking durch. Außerdem wird Ihr Objekt in Scheiben geschnitten. Tun Sie das nicht, geben Sie einen Zeiger zurück.

    
Luchian Grigore 02.02.2012 20:13
quelle
0

Um *new tile_tree_apple auszuführen, sollte der Konstruktor von tile_tree_apple aufgerufen werden, aber an dieser Stelle weiß der Compiler nichts über tile_tree_apple , er kann also den Konstruktor nicht verwenden.

Wenn Sie

eingeben %Vor%

in einer separaten cpp-Datei, die die Definition der Klasse tile_tree_apple hat oder die Header-Datei enthält, die die Definition hat, wird alles funktionieren.

    
Seagull 02.02.2012 20:21
quelle
-2

Ich bin ein CPP-Noob, aber müssen Sie nicht die Vererbung in der Forward-Deklaration angeben?

class tile_tree_apple : public tile;

    
Matthew 02.02.2012 20:15
quelle

Tags und Links