Listenerinterface der Basisklasse implementieren -> C4355

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Listenerinterface der Basisklasse implementieren -> C4355

Beitrag von kaiserludi »

Ich habe folgendes (hier veeinfach dargestelltes) Design:

Code: Alles auswählen

class Listener
{
public:
  virtual void callback(void) = 0;
};

class Base
{
public:
  Base(Listener* pListener);
private:
  Listener* mpListener;
};

class Subclass : public Base, Public Listener
{
public:
  Subclass(void);
};

Code: Alles auswählen

Base::Base(Listener* pListener)
  : mpListener = pListener
{
}

Subclass::Subclass(void)
  : Base(this)
{
}
Sprich, Subclass erbt sowohl von Base als auch von Listener, um das Callbackinterface seiner Basisklasse zu implementieren.
Die Basisklasse verlangt nun, dass man einen Pointer auf eine Implementation ihres Callbackinterfaces an ihren Konstruktor übergibt.
Die Übergabe des this-pointers an den Basisklassenkonstruktor führt allerdings in VS zum Warning C4355: "'this' : used in base member initializer list".

Da ich im Basisklassenkonstruktor nur den Pointer auf den übergebenen Listener in einer Membervariable abspeichere und sonst nicht auf die erbende Klasse zugreife, sollte das ganze problemlos funzen.

Gibt es elegantere Möglichkeiten, das Warning los zu werden, als via #pragma warning (disable : 4355 )?
Zuletzt geändert von kaiserludi am 13.01.2012, 11:02, insgesamt 1-mal geändert.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
Schrompf
Moderator
Beiträge: 4886
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: Listenerinterface der Basisklasse implementieren -> C435

Beitrag von Schrompf »

Ich bekomme die Warnung auch gelegentlich. Der Compiler warnt Dich halt, das evtl. Teile des Objekts noch nicht vollständig konstruiert sind, wenn der this-Empfänger darauf zugreift. Ich lebe bisher mit diesen Warnungen, mir ist noch kein schöner Weg drumrum eingefallen.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: Listenerinterface der Basisklasse implementieren -> C435

Beitrag von kaiserludi »

Schrompf hat geschrieben:Ich lebe bisher mit diesen Warnungen.
Das würde ich ungerne, einfach weil ich es von anderen Projekten kenne, dass ein Rebuild der Solution eben mal eine vierstellige Anzahl Warnings produziert und man immer viel Freude hat, wenn man gerade Code geschrieben hat, für den der Compiler ein weiteres generiert, welches aber in diesem Fall tatsächlich kritisch ist. Es geht in der Flut einfach unter. Daher versuche ich, die Warnings in Projekten, für die ich verantwortlich bin, gegen 0 zu halten.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
jumphigh
Beiträge: 19
Registriert: 30.06.2004, 13:41
Kontaktdaten:

Re: Listenerinterface der Basisklasse implementieren -> C435

Beitrag von jumphigh »

kaiserludi hat geschrieben:Daher versuche ich, die Warnings in Projekten, für die ich verantwortlich bin, gegen 0 zu halten.
Das ist vollkommen richtig so! Andere sehen sogar Warnungen als Fehler an und lassen den Code nicht durch. Ich würde an den fraglichen Stellen die Warnung einfach abstellen, wenn du dir sicher bist, dass im C'tor eben nicht auf das noch nicht vollständig konstruierte Objekt zugegriffen wird. In VC geht das mit

Code: Alles auswählen

 #pragma warning( once : 4355 ) 
direkt in der CPP vor dem C'tor.

Übrigens: Dein fehlerhaftes Beispiel findest du direkt in der Beschreibung zu C4355.

MfG
Andreas
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: Listenerinterface der Basisklasse implementieren -> C435

Beitrag von kaiserludi »

Am besten wäre es wohl, wenn der Compiler das Warning erst bei einem Zugriff auf den derived-Pointer in Konstruktor oder Destruktor schmeißen würde und nicht, bereits wenns einfach nur als Parameter übergeben wird, aber das war ihnen wohl in Sachen Implementierung zu komplex.

Ja, wie bereits geschrieben, mir ist bekannt, dass ich das Warning via pragma deaktivieren kann, aber ich habe gehofft, es gibt elegantere Ansätze, als einfach das Warning auszuschalten.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
jumphigh
Beiträge: 19
Registriert: 30.06.2004, 13:41
Kontaktdaten:

Re: Listenerinterface der Basisklasse implementieren -> C435

Beitrag von jumphigh »

kaiserludi hat geschrieben:Am besten wäre es wohl, wenn der Compiler das Warning erst bei einem Zugriff auf den derived-Pointer in Konstruktor oder Destruktor schmeißen würde und nicht, bereits wenns einfach nur als Parameter übergeben wird, aber das war ihnen wohl in Sachen Implementierung zu komplex.
In der Tat, warum sollte man für diesen seltenen Spezialfall eine vollständige Codeanalyse (die auch nur selten möglich ist) durchführen?
Ja, wie bereits geschrieben, mir ist bekannt, dass ich das Warning via pragma deaktivieren kann, aber ich habe gehofft, es gibt elegantere Ansätze, als einfach das Warning auszuschalten.
Nein, das Warning auszuschalten ist in so einem Fall genau das richtige Mittel weil begründbar. Dies ist auch nicht unelegant.

MfG
Andreas
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: Listenerinterface der Basisklasse implementieren -> C435

Beitrag von kaiserludi »

Hmm, ich frage mich gerade, was überhaupt der Nutzen dieses Warnings ist (G++ solls laut Google wohl auch nicht schmeißen). Ich könnte ja genauso gut den this-pointer nicht in der Initializer-list an den base-class Konsturktor übergeben, sondern in hinterher im Rumpf per setter setzen, dann kann zwar kein undefinierter Zugriff darauf im Konstruktor mehr passieren, aber er kann immer noch in einer Membervariablen gespeichert werden, um dann Funktionen im Base-Destruktor drauf aufzurufen, wenn der Konstruktor der abgeleiteten Klasse schon aufgerufen wurde. In dem Fall triggert das Warning aber auch nicht, obwohl die Situation nicht midner gefährlich ist.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Listenerinterface der Basisklasse implementieren -> C435

Beitrag von dot »

kaiserludi hat geschrieben:Hmm, ich frage mich gerade, was überhaupt der Nutzen dieses Warnings ist (G++ solls laut Google wohl auch nicht schmeißen). Ich könnte ja genauso gut den this-pointer nicht in der Initializer-list an den base-class Konsturktor übergeben, sondern in hinterher im Rumpf per setter setzen, dann kann zwar kein undefinierter Zugriff darauf im Konstruktor mehr passieren, aber er kann immer noch in einer Membervariablen gespeichert werden, um dann Funktionen im Base-Destruktor drauf aufzurufen, wenn der Konstruktor der abgeleiteten Klasse schon aufgerufen wurde. In dem Fall triggert das Warning aber auch nicht, obwohl die Situation nicht midner gefährlich ist.
Und wie genau sollte der Compiler dieses Verhalten detektieren? Der einzige Weg sowas zu 100% richtig zu erfassen wären Checks zur Laufzeit...

Mit Gewalt bekommt man alles kaputt, wer sowas macht ist einfach selbst schuld.
Antworten