forward-declaration

Forward-Deklarationen ermöglichen statisch typisierten Programmen, den Typ und den Namen eines Symbols anzugeben, ohne es tatsächlich zu definieren.
9
Antworten

C ++ Klassen-Forward-Deklaration

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 ... Wirklic...
02.02.2012, 20:10
3
Antworten

Deklarationen für Variablen weiterleiten?

Ich habe C-Code, den ich nach C ++ portieren muss. Der Code hat eine Struktur %Vor% Und jetzt werden zwei globale Arrays wie folgt deklariert und initialisiert: %Vor% Nun, während dies in C funktioniert, gibt es einen Fehler in C ++ (Var...
15.09.2010, 05:03
8
Antworten

___ qstntxt ___

Ich habe gerade begonnen, Qt zu lernen, indem ich ihr Tutorial benutze. Ich bin momentan auf Tutorial 7, wo wir eine neue LCDRange-Klasse erstellt haben. Die Implementierung von LCDRange (die .cpp-Datei) verwendet die Qt QSlider-Klasse, also in der .cpp-Datei ist

%Vor%

aber im Header ist eine Vorwärtsdeklaration:

%Vor%

Laut Qt

  

Dies ist ein weiterer klassischer Trick, der aber viel seltener verwendet wird. Da wir QSlider nicht in der Schnittstelle der Klasse benötigen, verwenden wir nur in der Implementierung eine Vorwärtsdeklaration der Klasse in der Headerdatei und enthalten die Headerdatei für QSlider in der .cpp-Datei.

     

Dies macht die Kompilierung von großen Projekten viel schneller, weil der Compiler die meiste Zeit damit verbringt, Headerdateien zu analysieren, nicht den eigentlichen Quellcode. Dieser Trick allein kann Compilations oft um einen Faktor von zwei oder mehr beschleunigen.

Lohnt sich das? Es scheint sinnvoll zu sein, aber es ist noch eine Sache zu verfolgen - ich denke, es wäre viel einfacher, nur alles in die Header-Datei aufzunehmen.

    
___ answer791135 ___

Die Standardbibliothek tut dies für einige der iostream-Klassen im Standard-Header %code% . Es ist jedoch keine allgemein anwendbare Technik - beachten Sie, dass es keine Header für die anderen Standard-Bibliothekstypen gibt, und es sollte nicht (IMHO) Ihr Standardansatz beim Entwurf von Klassenherarchien sein.

Obwohl dies eine beliebte "Optimierung" für Programmierer ist, vermute ich, dass, wie die meisten Optimierungen, nur wenige von ihnen den Build ihrer Projekte sowohl mit als auch ohne solche Deklarationen zeitlich abgestimmt haben. Meine begrenzten Experimente in diesem Bereich zeigen, dass die Verwendung von vorkompilierten Headern in modernen Compilern es unnötig macht.

    
___ answer791191 ___

Es gibt einen RIESIGEN Unterschied in den Kompilierungszeiten für größere Projekte, sogar für solche mit sorgfältig verwalteten Abhängigkeiten. Sie sollten sich die Angewohnheit zunutze machen, die Header-Dateien so weit wie möglich zu deklarieren und zu behalten, da in vielen Softwareshops, die C ++ verwenden, dies erforderlich ist. Der Grund dafür, warum Sie es nicht allzu oft in den Standard-Header-Dateien sehen, liegt darin, dass diese stark von Templates Gebrauch machen, an welchem ​​Punkt die Vorwärts-Deklaration schwierig wird. Bei MSVC können Sie mit / P prüfen, wie die vorverarbeitete Datei vor der eigentlichen Kompilierung aussieht. Wenn Sie keine Vorwärtsdeklaration in Ihrem Projekt gemacht haben, wäre es wahrscheinlich eine interessante Erfahrung zu sehen, wie viel zusätzliche Verarbeitung erforderlich ist.

    
___ answer791185 ___

Im Allgemeinen, nein.

Ich habe so viel wie möglich weitergeleitet, aber nicht mehr.

Was Qt betrifft, können Sie feststellen, dass es eine %code% include-Datei gibt, die alle GUI-Widgets anzieht. Außerdem gibt es eine %code% , %code% , %code% usw. Es gibt eine Header-Datei für jedes Modul. Es scheint, dass das Qt-Team glaubt, dass dies die bevorzugte Methode ist. Das sagen sie in ihrer Moduldokumentation.

True, die Kompilierungszeit kann erhöht werden. Aber meiner Erfahrung nach ist es nicht so viel. Und wenn dies der Fall wäre, wäre die Verwendung vorkompilierter Header der nächste Schritt.

    
___ answer791264 ___

Wenn Sie schreiben ...

enthält "foo.h"

... damit weisen Sie ein konventionelles Build-System an "Jedes Mal, wenn sich Änderungen in der Bibliotheksdatei foo.h ergeben, verwerfen Sie diese Kompilierungseinheit und bauen sie neu auf, selbst wenn foo.h nur zufällig hinzugefügt wurde ein Kommentar oder die Hinzufügung eines Kommentars zu einer Datei, die foo.h enthält, selbst wenn alles, was passierte, ein ultra-anspruchsvoller Kollege war, der die geschweiften Klammern neu ausbalancierte, selbst wenn nichts passierte, als ein unter Druck stehender Kollege in foo.h eincheckte unverändert und änderte versehentlich seinen Zeitstempel. "

Warum möchten Sie einen solchen Befehl ausgeben? Bibliotheksheader haben, weil sie im Allgemeinen mehr menschliche Leser als Anwendungsheader haben, eine besondere Anfälligkeit für Änderungen, die keine Auswirkungen auf die Binärdatei haben, wie beispielsweise eine verbesserte Dokumentation von Funktionen und Argumenten oder die Erhöhung einer Versionsnummer oder eines Copyright-Datums. p>

Die C ++ -Regeln ermöglichen, dass Namespace an beliebiger Stelle in einer Kompilierungseinheit (im Gegensatz zu einer struct oder Klasse ) der Reihe nach geöffnet wird Vorwärtsdeklaration unterstützen.

    
___ answer791190 ___

Vorwärtsdeklarationen sind sehr nützlich, um die zirkulären Abhängigkeiten zu brechen, und manchmal ist es in Ordnung, sie mit eigenem Code zu verwenden, aber wenn sie mit Bibliothekscode verwendet werden, kann das Programm auf einer anderen Plattform oder mit anderen Versionen der Bibliothek brechen sogar mit deinem Code, wenn du nicht vorsichtig genug bist). IMHO nicht wert.

    
___ tag123c ___ C ++ ist eine universelle Programmiersprache. Es wurde ursprünglich als Erweiterung von C entworfen und behält eine ähnliche Syntax, ist aber jetzt eine komplett andere Sprache. Verwenden Sie dieses Tag für Fragen zu Code, der mit einem C ++ - Compiler kompiliert werden soll. ___ tag123forwarddeclaration ___ Forward-Deklarationen ermöglichen statisch typisierten Programmen, den Typ und den Namen eines Symbols anzugeben, ohne es tatsächlich zu definieren. ___ answer791121 ___

Ja, es hilft sicher. Eine weitere Sache, die Sie Ihrem Repertoire hinzufügen können, sind vorkompilierte Header, wenn Sie sich Sorgen um die Kompilierungszeit machen.

Nachschlagen FAQ 39.12 und 39.13

    
___ answer791176 ___

Absolut. Das C / C ++ Build-Modell ist ... ähem ... ein Anachronismus (um das Beste zu sagen). Bei großen Projekten wird es zu einer ernsten PITA.

Wie Neil richtig feststellt, sollte dies nicht der Standardansatz für Ihr Klassendesign sein, gehen Sie nicht umhin, es sei denn, Sie müssen es wirklich tun.

Breaking Circular include Referenzen ist der eine Grund, warum Sie Forward-Deklarationen verwenden müssen.

%Vor%

Wiederherstellungszeit reduzieren - Stellen Sie sich den folgenden Code vor

%Vor%

Jetzt zieht jede .cpp-Datei, die Foo.h direkt oder indirekt einbezieht, auch QSlider.h und alle seine Abhängigkeiten ein. Das können Hunderte von .cpp-Dateien sein! (Vorkompilierte Header helfen ein wenig - und manchmal sehr viel - aber sie setzen den Platten- / CPU-Druck im Speicher- / Platten-Druck um und treffen bald darauf das "nächste" Limit)

Wenn der Header nur eine Referenzdeklaration erfordert, kann diese Abhängigkeit oft auf einige wenige Dateien beschränkt sein, z. foo.cpp.

Reduzierung der inkrementellen Build-Zeit - Der Effekt ist noch ausgeprägter, wenn Sie mit eigenen (und nicht mit einer stabilen Bibliothek) Kopfzeilen arbeiten. Stellen Sie sich vor, Sie haben

%Vor%

Wenn nun die meisten Ihrer .cpps bar.h ziehen müssen, ziehen sie indirekt auch foo.h. Jede Änderung von foo.h löst also alle diese .cpp-Dateien aus (die Foo vielleicht nicht einmal kennen müssen!). Wenn bar.h stattdessen eine Forward-Deklaration für Foo verwendet, ist die Abhängigkeit von foo.h auf bar.cpp beschränkt:

%Vor%

Es ist so üblich, dass es ein Muster ist - das PIMPL-Muster . Die Verwendung ist zweifach: Erstens bietet sie eine echte Schnittstellen- / Implementierungsisolation, die andere reduziert Buildabhängigkeiten. In der Praxis würde ich ihre Nützlichkeit 50:50 gewichten.

Sie benötigen eine Referenz in der Kopfzeile, Sie können keine direkte Instantiierung des abhängigen Typs haben. Dies begrenzt die Fälle, in denen Vorwärtsdeklarationen angewendet werden können. Wenn Sie dies explizit tun, ist es üblich, eine Dienstprogrammklasse zu verwenden (z. B. boost :: scoped_ptr ) dafür.

Ist Build Time es wert? Definitiv , würde ich sagen. Im schlimmsten Fall wächst die Build-Zeit mit der Anzahl der Dateien im Projekt. Andere Techniken - wie schnellere Maschinen und parallele Builds - können nur prozentuale Gewinne liefern.

Je schneller der Build, desto häufiger testen die Entwickler, was sie getan haben. Je öfter Komponententests ausgeführt werden, desto schneller können die Build-Breaks behoben werden, und die Entwickler zögern oft.

Wenn Sie in der Praxis Ihre Build-Zeit verwalten, während sie für ein großes Projekt (z. B. Hunderte von Quelldateien) unerlässlich ist, macht dies bei kleinen Projekten immer noch einen "Komfortunterschied" aus. Das Hinzufügen von Verbesserungen im Nachhinein ist oft eine Geduldsprobe, da ein einzelner Fix nur Sekunden (oder weniger) eines 40-minütigen Builds abschneidet.

    
___ answer791178 ___

Ich benutze es die ganze Zeit. Meine Regel ist, wenn es den Header nicht benötigt, dann setze ich eine Vorwärtsdeklaration ( "verwende Header, wenn du musst, verwende Vorwärtsdeklarationen wenn du kannst" ). Die einzige Sache, die saugt, ist, dass ich wissen muss, wie die Klasse deklariert wurde (struct / class, vielleicht, wenn es eine Vorlage ist, brauche ich ihre Parameter, ...). Aber in der überwiegenden Mehrheit der Fälle kommt es nur auf %code% oder etwas in diesem Bereich. Wenn etwas mehr Aufwand erfordert, um einfach deklariert zu werden, kann man immer einen speziellen forward declare-Header deklarieren, wie es der Standard auch mit %code% tut.

Wenn Sie die Header-Datei nicht einbeziehen, wird nicht nur die Kompilierzeit reduziert, sondern auch der Namensraum wird nicht verschmutzt. Dateien einschließlich der Kopfzeile werden Ihnen dafür danken, dass Sie so wenig wie möglich einbeziehen, damit Sie weiterhin eine saubere Umgebung verwenden können.

Dies ist der grobe Plan:

%Vor%

Es gibt intelligente Zeiger, die speziell dafür entwickelt wurden, mit Zeigern auf unvollständige Typen zu arbeiten. Eine sehr bekannte ist %code% .

    
___

Ich habe gerade begonnen, Qt zu lernen, indem ich ihr Tutorial benutze. Ich bin momentan auf Tutorial 7, wo wir eine neue LCDRange-Klasse erstellt haben. Die Implementierung von LCDRange (die .cpp-Datei) verwendet die Qt QSlider-Klasse, also in...
26.04.2009, 16:15
6
Antworten

Ist es möglich, eine Klasse zu deklarieren, ohne sie zu implementieren? (C ++)

Ich weiß, dass die Fragen mehrdeutig erscheinen, aber ich kann mir keinen anderen Weg vorstellen, es zu sagen, aber, ist es möglich, so etwas zu tun: %Vor% ?     
16.05.2009, 01:50
5
Antworten

Kopfzeile in Ziel importieren c

In Objective-c, wenn wir das Objekt einer Klasse per Konvention in einer anderen Klasse verwenden, sollten wir die Klasse in der .h-Datei deklarieren, d. h. @class classname; . Und sollte die Headerdatei in der .m-Datei importieren, d. H.% Co_...
10.05.2012, 10:09
2
Antworten

Declare aber nicht definieren innere Struktur / Klasse - legal C ++ oder nicht?

Folgt der folgende Code C ++ oder nicht? %Vor% Sowohl Visual C ++ als auch GCC akzeptieren es, aber der Code scheint mir etwas seltsam zu sein und ich würde es hassen, ihn von irgendeinem zukünftigen Compiler ablehnen zu lassen. Dennoch s...
14.10.2009, 07:42
1
Antwort

Wie können zwei Strukturen implementiert werden, die aufeinander zugreifen können?

Der Code, den ich geschrieben habe: %Vor% Die Kompiliernachricht: %Vor% Ich weiß, warum dieser Code nicht korrekt ist, aber ich weiß nicht, wie man zwei Strukturen implementiert, die aufeinander zugreifen können. Gibt es einen eleganten...
25.04.2013, 09:00
1
Antwort

Was kann ich in C ++ "weiterleiten"?

Ich weiß, dass ich es tun kann %Vor% und wahrscheinlich %Vor% und globale Funktionen %Vor% Was ist mit einer typisierten Enum? Was ist mit einem typisierten Enum in einer nicht deklarierten Klasse? Was ist mit einer Funktion mit eine...
26.09.2010, 21:11
2
Antworten

Definiere vorwärts deklarierte C-Struktur als C ++ - Struktur

Ist es legal, eine struct als C- struct weiterzuleiten? %Vor% und definieren Sie es anschließend als C ++ - struct , d. h. als Nicht-POD-Typ? %Vor% Die allgemeine Absicht besteht darin, über eine C-Schnittstelle einen extern zugä...
10.07.2013, 10:50
4
Antworten

Vorwärtsdeklarationen und shared_ptr

Ich versuche, meinen Code zu refactorieren, so dass ich Vorwärtsdeklarationen verwende, anstatt viele Header einzubeziehen. Ich bin neu und habe eine Frage zu boost :: shared_ptr. Sagen wir, ich habe die folgende Schnittstelle: %Vor% Ich...
16.05.2013, 12:56