Kann mir jemand helfen, dieses Verhalten zu verstehen? Um kurz:Seltsames Verhalten beim Extrahieren einer bekannten Schnittstelle aus einem polymorphen Container
- ich polymorphe Objekte in einem gemeinsamen Behälter gespeichert haben.
- Einige von ihnen implementieren eine bestimmte Schnittstelle. Ich kann sagen, welche.
- Aber ich kann diese Schnittstelle nicht verwenden.
Hier ist, was ich boilt es haben bis zu:
#include <iostream>
#include <vector>
// A base class
struct Base {
// A polymorphic method
virtual void describe() const {
std::cout << "Base" << std::endl;
};
virtual ~Base(){
std::cout << " Base destroyed" << std::endl;
};
};
// A specific interface
struct Interface {
virtual ~Interface(){
std::cout << " Interface Destroyed" << std::endl;
};
virtual void specific() = 0;
};
// A derived class..
struct Derived : public Base, public Interface {
virtual void describe() const {
std::cout << "Derived" << std::endl;
};
virtual void specific() {
std::cout << "Derived uses Interface" << std::endl;
};
virtual ~Derived() {
std::cout << " Derived destroyed" << std::endl;
};
};
int main() {
// Test polymorphism:
Base* b(new Base());
Derived* d(new Derived());
b->describe(); // "Base"
d->describe(); // "Derived"
// Ok.
// Test interface:
d->specific(); // "Derived uses Interface"
Interface* i(d);
i->specific(); // "Derived uses Interface"
// Ok.
// Here is the situation: I have a container filled with polymorphic `Base`s
std::vector<Base*> v {b, d};
// I know that this one implements the `Interface`
Interface* j((Interface*) v[1]);
j->specific(); // " Derived destroyed"
// " Interface destroyed"
// " Base destroyed"
// Why?! What did that object do to deserve this?
return EXIT_SUCCESS; // almost -_-
}
Kann mir jemand sagen, was ich dort bin fehlt?
Interessant: Wenn ich die Definitionen von Base::~Base
und Base::describe
tauschen, dann das Objekt beschreibt sich stattdessen zerstört zu werden. Wie kommt es, dass der Auftrag in Methodendeklarationen eine Rolle spielt?
Aus Interesse, 'Interface * j = static_cast (v [1]);' scheint auch zu funktionieren, ist es sicher? –
@ChrisDrew Solange Sie * wissen *, dass '* v [1]' tatsächlich eine Instanz von 'Derived' ist (oder eine davon abgeleitete Klasse), ist es sicher. – Angew
@ChrisDrew Ja, das ist in Ordnung, weil du weißt, dass es ein 'Derived *' ist, also ist der 'static_cast' OK. Und dann Zeiger zu abgeleitet ('Derived *') zu Zeiger-zu-Basis ('Interface *') ist eine Standardkonvertierung, dass man immer OK ist. 'dynamic_cast' ist sicherer (aber langsamer), denn wenn' v [1] 'kein' Derived * 'wäre, würden Sie ein wohldefiniertes Ergebnis (einen Nullzeiger) anstelle eines gültig aussehenden Zeigers erhalten, der undefiniertes Verhalten ergibt wenn du es benutzt. – Barry