2016-03-20 4 views
2

Ich möchte nicht vorhandene virtuelle Methoden zu einer vorhandenen Klasse A hinzufügen, die ich nicht ändern kann. Deshalb erstelle ich eine Klasse B geerbt von A und füge die Methoden hinzu, die ich will. Wenn ich nun ein Objekt vom Typ A habe, kann ich es einfach als Objekt vom Typ B betrachten? Sprich, ist der folgende Code Recht ?:Darf in C++ in eine abgeleitete Klasse umgewandelt werden, die nur nicht-virtuelle Methoden hinzufügt?

class A { <...> }; 

class B: public A { 
    void f(); 
    }; 

A a(); 
void g(const B&); 
void h() { g(static_cast<B&&>(a())); } 

Es ist zu kompilieren und zu arbeiten, aber ich frage mich, ob es durch den Standard garantiert wird wie erwartet zu funktionieren. Ich sehe nicht, warum nicht, aber es fühlt sich nicht sehr sauber an.

+0

Nein, die Besetzung verursacht undefiniertes Verhalten –

+0

Aber 'B a;' gefolgt von einem Aufruf an eine Funktion, die ein 'A &' als Argument nimmt, wie in 'void foo (A & a);') und es als legal und Definiert: 'foo (a)' so dass innerhalb von foo, wenn du wirklich weißt, dass 'a' wirklich ein' b' ist (aber wie wärst du?), kannst du den Cast durchführen –

+0

Warum willst du ein Objekt werfen? in etwas ist es nicht? – MikeMB

Antwort

5

Das ist undefiniertes Verhalten. Von [expr.static.cast]:

einen L-Wert vom Typ „CV1 B“, wobei B ein Klasse-Typ ist, kann gegossen werden „Bezugnahme auf CV2 D“ eintippen, wobei D eine Klasse ist abgeleitet (Ziffer 10) von B , wenn eine gültige Standardkonvertierung von "Zeiger auf D" zu "Zeiger auf B" existiert (4.10), cv2 ist die gleiche cv-Qualifikation wie oder höher cv-qualification als cv1, und B ist weder eine virtuelle Basisklasse von D noch eine Basisklasse einer virtuellen Basisklasse von D. Das Ergebnis hat den Typ "cv2 D". Ein xvalue vom Typ "cv1 B" kann umgewandelt werden, um "rvalue reference to cv2 D" mit denselben Einschränkungen wie für einen lvalue des Typs "cv1 B" zu schreiben. Wenn das Objekt vom Typ "cv1 B" eigentlich ein Unterobjekt eines Objekts vom Typ D ist, bezieht sich das Ergebnis auf das umschließende Objekt vom Typ D. Ansonsten ist das Verhalten undefiniert.

a ist nicht wirklich ein suboject eines Objekts vom Typ B - es ist wirklich nur vom Typ A, so ist das Verhalten undefiniert.

Was ist Ihnen zu stoppen einfach ein Nicht-Mitglied-Funktion hinzugefügt:

void f(A&); 

Wenn die Antwort ist, dass Sie private oder protected Mitglieder A zugreifen müssen, dann war es Absicht, diese Mitglieder unaccessible zu machen Sie!

+0

Nichts hält mich auf, es ist einfach Durch die Verwendung einer globalen Funktion verliere ich einen der Vorteile von OOP. Zu schlecht C++ bietet keine Lösung für dieses Problem. –

+1

@ YaronCohen-Tal Klingt mehr nach mir, als hättest du einen der Nachteile von OOP entdeckt. – Barry

+0

Hehe, ja, vielleicht ... Das ist es, ich wechsle zu C! j.k ... –

Verwandte Themen