2010-02-03 12 views
9

Was bedeutet C4250 Visual C + Warnung in der Praxis bedeuten? Ich habe die verknüpfte MSDN-Seite gelesen, bekomme aber immer noch nicht das Problem.Was bedeutet C4250 VC++ - Warnung?

Worüber warnt mich der Compiler und welche Probleme könnten auftreten, wenn ich die Warnung ignoriere?

+1

Die Erklärung in dem MSDN-Artikel widerspricht sich."Der in Klasse 2 wird geerbt, weil er eine Basisklasse ist" - aber Klasse2 ist die abgeleitete Klasse, nicht die Basisklasse in ihrem Beispiel. – MSalters

+0

@MSalters: Ich kann den Widerspruch nicht sehen. Sie verwenden 'class2' nicht in ihren Beispielen. Tatsächlich geben sie in ihren ausgearbeiteten Beispielen niemals ein Beispiel für den Text der Warnung. – quamrana

+0

@MSalters Ich empfehle Ihnen, es erneut zu lesen! class2 ist die BASE-Klasse. – CinCout

Antwort

20

Die Warnung wird darauf hingewiesen, dass, wenn irgendwelche weak Klassen Operationen auf vbc virtuelle Operationen abhängen, die in dominant umgesetzt werden, dann könnten diese Vorgänge Verhalten aufgrund der Tatsache ändern, dass sie in einer Diamant-Vererbungshierarchie gebündelt werden.

struct base { 
    virtual int number() { return 0; } 
}; 
struct weak : public virtual base { 
    void print() { // seems to only depend on base, but depends on dominant 
     std::cout << number() << std::endl; 
    } 
}; 
struct dominant : public virtual base { 
    int number() { return 5; } 
}; 
struct derived : public weak, public dominant {} 

int main() { 
    weak w; w.print(); // 0 
    derived d; d.print(); // 5 
} 

dass das Verhalten ist, dass die Norm spezifiziert, aber es könnte für den Programmierer zu Zeiten, die weak::print Betriebsverhalten geändert haben aufgrund einer überschriebenen Methode oben oder unten in der Hierarchie, sondern von einem Geschwister überraschend Klasse in der Vererbungshierarchie, wenn sie von derived aufgerufen wird. Beachten Sie, dass es vom Standpunkt der derived Sicht sinnvoll ist, dass es eine Operation aufruft, die von einer virtuellen Methode abhängt, die in dominant implementiert ist.

+1

Gut, was ich nicht bekomme: Wie wird festgestellt, welche Klasse dominant ist? In der Reihenfolge der Liste der Klassen, von denen erben? – flohack

+0

@flohack: Ich bin mir nicht sicher, dass * dominant * vs. * schwach * die richtige Terminologie ist oder ob es mehr verwirrt als hilft ... Wenn Sie an ein Vererbungsdiagramm denken, wobei Knoten Typen und Pfeile Vererbungsbeziehungen sind, Das letzte Objekt wird mehrere Pfade von den Basen zum * one * vollständigen Objekt haben. In jedem Pfad gibt es * einen * endgültigen Überrider für jede virtuelle Funktion in den Basen, in einem der Typen, der dem * vollständigen * Objekt näher ist. –

+1

... man sich die virtuelle Vererbung als Verzweigung im Graphen vorstellen kann, wenn der letzte Overrider für einen der Zweige über dem Splitpunkt liegt und der andere Zweig einen späteren Overrider liefert, ersetzt er den Overrider für beide Zweige. Auf der Ebene des * complete * -Objekts (der real konstruierte Typ) muss sich der finale Overrider in allen Pfaden auf den gleichen Typ beziehen. Wenn dies nicht der Fall ist, erhalten Sie einen Fehler zur Kompilierzeit. –

14

Dies bedeutet, dass der Compiler bemerkt hat, dass Sie ein weniger bekanntes Feature der virtuellen Vererbung verwenden, für das es einen Namen hat. Ich habe keine Ahnung, warum sie es für eine gute Idee hielten, es zu einer Warnung zu machen, aber es hat keine praktische Bedeutung; Der Code sollte so funktionieren, wie die Sprache es spezifiziert, er weist nicht auf einen Compiler-Mangel hin.

+0

Kein Scherz, und um es noch mysteriöser zu machen, warum ist es eine Warnung der Stufe 2 und nicht eine Stufe 4 (wie "nicht referenzierte lokale Variable" oder "Variable initialisiert, aber nie benutzt")? – davidbak

2

Im linked Beispiel Sie diamond haben, die sowohl weak und dominant erbt, die beide von vbc praktisch erben, sondern nur dominant Überschreibungen func()

Es gibt ein Problem in C++, wenn Sie eine solche Struktur aufweisen, wenn Sie don 't Verwenden Sie virtuelle Vererbung. Allerdings mit virtuelle Vererbung, ist das Problem gelöst, so dass die Warnung nur Informationen Sie sagen, dass, wenn:

  1. Sie nicht virtuelle Vererbung benutzt hatte, ODER
  2. weak hatte func() umgesetzt

dann würden Sie einen Compiler-Fehler bekommen.

Also meine Meinung ist, dass wenn Sie wissen, was Sie tun, Sie sicher diese Warnung für das gesamte Projekt deaktivieren können.

2

In VS2012 können Sie diese Warnung für "nichts" erhalten, aber eine Klasse von iostream erben. Die MS-Rückmeldung article besagt, dass diese Warnung in diesem Fall ignoriert werden kann.

Wenn Sie nicht über diese Art von Warnungen wollen, zu unterdrücken, sondern einen Cross-Plattform-Code mögen, die nicht diesen Müll Warnung unter vs2012 produziert, schlägt ein article on C4250 bei CodeInPro diese do-nothing Zeilen zu Ihrem Code hinzuzufügen in die Klasse, die von einem Iostream erbte:

void _Add_vtordisp1() { } // Required to avoid VC++ warning C4250 
void _Add_vtordisp2() { } // Required to avoid VC++ warning C4250 
Verwandte Themen