Hallo zusammen,
ich versuche das Visitor Pattern nach der Wiki-Vorlage zu verwenden:
https://en.wikipedia.org/wiki/Visitor_pattern#C.2B.2B_example
Doch bekomme ich im Client bei dem Aufruf der Dispatch Methode die
Meldung der Typ sei incomplete. Was ich nicht verstehe, da mir die
Methode "DispShowCall()"sogar vorgeschlagen wurde.
Hat jemand einen Vorschlag?
> Doch bekomme ich im Client bei dem Aufruf der Dispatch Methode die> Meldung der Typ sei incomplete.
Ich sehe weder eine Methode 'Dispatch()', noch einen Aufruf selbiger,
und schon garkeine Compilermeldung.
> Hat jemand einen Vorschlag?
Originalcode und -fehlermeldung zeigen, nicht irgendetwas das zufällig
in der Zwischenablage war.
>Ich sehe weder eine Methode 'Dispatch()', noch einen Aufruf selbiger,>und schon garkeine Compilermeldung.
Was meinst du wohl, soll
>DispShowCall();
heißen.
Hallo Fremder,
Nur mal so als Tipp: das ist hier keine kostenpflichtige
Beratungsstelle, für die Dein Arbeitgeber bezahlt hat.
Was kann den so schwerr daran sein, den gezeigten Code so zu
formatieren/annotieren, dass man ihn lesen kann? (direkt über dem Feld,
in den Du den code gerotzt hast, gibt es Informationen zu Formatierung).
Warum zeigst Du uns nicht die Fehlermeldung des compilers? Du fragst
uns, was der Compiler damit meint, gibst uns aber nur eine von Dir
interpretierte Version.
Wenn Dich jemand nach mehr Details fragt: warum gibst Du ihm dann nicht
die Information? (und entschuldigst ggf. sogar dafür, dass Du das im
ursprünglichen Post vergessen hattest). Du guckst da schon seit Stunden
auf Dein Problem und übersiehst dabei vielleicht, dass Du beim
Formulieren Deiner Frage wichtige Details vergessen hast.
So, jetzt zu eigentlichen Frage:
Wenn der Compiler sich über einen "incomplete type" beschwerrt, dann hat
er halt an dieser Stelle bis dato nur einen "incomplete type" (aka
forward declaration) gesehen. Wenn das tatsächlich beim Versuch, über
einen Pointer oder eine Referenz auf ein Objekt eine member function
aufzurufen, dann fehlt halt die Definition der Klasse.
Wahrscheinlich Node_I. Da können wir aber auch nur raten, da der von Dir
gepostete Code keinen einzigen Funktionsaufruf enthält.
mfg Torsten
Milhouse schrieb:> ich versuche das Visitor Pattern nach der Wiki-Vorlage zu verwenden:> https://en.wikipedia.org/wiki/Visitor_pattern#C.2B.2B_example> Doch bekomme ich im Client bei dem Aufruf der Dispatch Methode die> Meldung der Typ sei incomplete.
Dann ist das wohl so.
> Was ich nicht verstehe, da mir die> Methode "DispShowCall()"sogar vorgeschlagen wurde.
Vom Compiler?
> Hat jemand einen Vorschlag?
Von Incomplete Types kannst du i.W. Adressen herumschubsen, mehr nicht.
>>>Der Client "Node_Junction">>#include "..\UIs\ui_visitor_i.h"
Tippfhler. "/" anstatt "\" — und ja, auch under Windos und auch wenn's
in Wikipedia mit "\" stehen sollte.
>>class Node_Junction : public Node_I>>{>>public:>> Node_Junction(int arg = 0);>> virtual void Show(UI_Visitor_I *uiVisitor) override>> {>> (*uiVisitor).DispShowCall(this);>> }
UI_Visitor_I ist offenbar incomplete; insbesondere kannst du keinen
Zeiger darauf dereferenzieren, was du mit uiVisitor->DispShowCall...
aber versuchst.
Üblicherweise ist Ziel der Übung, nicht den kompletten, UI_Visitor_I
definierenden Header und Sermon in X anderen Headern includen zu müssen,
sondern lediglich in Modulen, welche den kompletten Typ kennen (müssen).
Und / oder es wird damit vermieden, zyklische Klassenabhängigkeiten zu
bekommen, denn für einen Incomplete Type benötigt man lediglich ein
lapidares
struct Foo;
union Foo;
was-auch-immer Foo;
Implementier Show() also im adäquaten Modul nach Include der benötigten
Klassendefnition — wo auch immer du die untergebracht hast.
Weiters kann der Anlass für diese Diagnostic der Umstieg auf eine neuere
g++ Version sein, die bestimmte "ill-formed, no diagnostic required"
Konstrukte nicht mehr toleriert.
Wie immer bei einem Umstieg auf eine neue Tool-Version, hat man
natürlich alle zwischenzeitlich angesammelten Release-Notes und
Porting-To Anleitungen studiert; hier insbesondere
https://gcc.gnu.org/gcc-7/porting_to.html
Mist, es geht...
Soll heißen, ich habs beseitigt und jetzt gehts, aber leider Abends mit
nem dunen Kopf und weiß nicht mehr, was ich verändert habe...
Wäre sicher lehrreich gewesen.
Milhouse schrieb:> Soll heißen, ich habs beseitigt und jetzt gehts, aber leider Abends mit> nem dunen Kopf und weiß nicht mehr, was ich verändert habe...
Man sollte auch privat die Sourcen immer in einer Versionsverwaltung wie
git oder Subversion vorhalten. Dann lassen sich solche fragen leicht mit
einem diff beantworten...
>Man sollte auch privat die Sourcen immer in einer Versionsverwaltung
stimmt schon...
Aber ich hab mich dabei gefragt - wie haltet ihr das mit der "Commit
Policy"?
Wahrscheinlich hätte ich den Stand eh nicht commited, weil er gar nicht
compilierbar war...
Ich würde nur Sachen comitten, die wenigesten compilierbar sind. (?)
Milhouse schrieb:>>Man sollte auch privat die Sourcen immer in einer Versionsverwaltung> stimmt schon...> Aber ich hab mich dabei gefragt - wie haltet ihr das mit der "Commit> Policy"?> Wahrscheinlich hätte ich den Stand eh nicht commited, weil er gar nicht> compilierbar war...> Ich würde nur Sachen comitten, die wenigesten compilierbar sind. (?)
Für mich ist das nicht zwingend erforderlich. Wenn ich eine größere
Änderung mache, bei der der Code über eine gewisse Zeit nicht
compilierfähig ist, will ich nicht erst warten, bis alles komplett
fertig ist, bevor ich meinen Commit mache. Denn ich will nicht, wenn ich
nach 90% getaner Arbeit durch Schusseligkeit den frischen Code
kaputtgemacht oder gar die bearbeiteten Files ganz gelöscht habe,
nochmal komplett von vorne anfangen müssen.
Ich finde, es gibt nix schlimmeres als Code, den man sich mühsam
erarbeitet hat, nach versehentlichem Vernichten ein zweites mal
schreiben zu müssen.
Wenn das Repository nur für dich alleine ist, ist das ja auch nicht
schlimm. Wenn man dagegen in der Gruppe arbeitet, ist das etwas anderes.
Da brauchen die anderen eine compilierfähige Version im Repo. Da muss
man sich dann was überlegen.
Rolf M. schrieb:> Wenn das Repository nur für dich alleine ist, ist das ja auch nicht> schlimm. Wenn man dagegen in der Gruppe arbeitet, ist das etwas anderes.> Da brauchen die anderen eine compilierfähige Version im Repo. Da muss> man sich dann was überlegen.
Dafür gibts Branches. Bevor man anfängt funktionierenden Code weiträumig
umzugraben oder überhaupt irgendetwas etwas anfängt was länger dauern
wird bis es fertig ist einfach schnell nen neuen Branch erzeugen. Dann
kommt man keinem in die Quere.
Bernd K. schrieb:> Dafür gibts Branches [...] schnell nen neuen Branch erzeugen.> Dann kommt man keinem in die Quere.
Bestenfalls die Hydra beim Mergen :-)
Bernd K. schrieb:> Rolf M. schrieb:>> Wenn das Repository nur für dich alleine ist, ist das ja auch nicht>> schlimm. Wenn man dagegen in der Gruppe arbeitet, ist das etwas anderes.>> Da brauchen die anderen eine compilierfähige Version im Repo. Da muss>> man sich dann was überlegen.>> Dafür gibts Branches.
Ja, wenn man große Umbauten macht, schon. Aber es ist ja auch nicht Sinn
der Sache, dass man für jede Änderung erst brancht, weil sie ggf.
temporär mal nicht compilierbar ist.
Rolf M. schrieb:> Aber es ist ja auch nicht Sinn> der Sache, dass man für jede Änderung erst brancht
Warum? Branchen kostet doch nichts, warum also damit geizen?
Man beschriftet einen Zettel und klebt ihn an die angefangene Arbeit.
Den "das-funktioniert"-Zettel lässt man da kleben wo er ist. Wenn man
fertig ist kann man überflüssige Zettel wieder wegwerfen.
Beschriftete Zettel die an Dingen kleben die von außen alle gleich
aussehen aber nur eins davon ist zu benutzen sind Gold wert. Man kann
gar nicht genug von diesen Aufklebern haben. Zum Glück kann man die
Aufkleber bei git von einer kostenlosen Endlos-Rolle abreißen und
überall hinkleben wo man will, nach Herzenslust, zum Nulltarif! Nennt
sich Branch. Ungefähr so nützlich wie Dateinamen statt Nummern.