Ich verwende das Besuchermuster, um mit vielen verschiedenen AST-Problemen umzugehen, was sehr gut funktioniert. Zum Beispiel verwende ich es, um nach statischem Typ zu suchen. Dies funktioniert gut, wenn nach dem genauen Typ gesucht wird, jedoch nicht für abgeleitete Klassen. Wenn wir Derived
haben, die von Base
erben, wird gefragt, ob ein Derived
Objekt ein Base
Fehler ist.Verwenden eines Besuchermusters zum Überprüfen des abgeleiteten Klassentyps?
Betrachten Sie den folgenden C++ Code:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
class Base;
class Derived;
class Visitor {
public:
virtual void visit(Base& object) = 0;
virtual void visit(Derived& object) = 0;
};
class EmptyVisitor : public Visitor {
public:
virtual void visit(Base& object) override {}
virtual void visit(Derived& object) override {}
};
template <class TYPE> class LogicVisitor : public EmptyVisitor {
public:
LogicVisitor(function<void(TYPE&)> logic) : EmptyVisitor(), logic(logic) {}
virtual void visit(TYPE& object) override { logic(object); }
private:
function<void(TYPE&)> logic;
};
class Base {
public:
virtual void accept(Visitor* visitor) {
visitor->visit(*this);
}
};
class Derived : public Base {
public:
virtual void accept(Visitor* visitor) override {
visitor->visit(*this);
}
};
template <class TYPE> bool is_type(shared_ptr<Base> base)
{
bool is_type = false;
LogicVisitor<TYPE> logic_visitor([&](TYPE& object) {
is_type = true;
});
base->accept((Visitor*)&logic_visitor);
return is_type;
}
int main() {
auto base = make_shared<Base>();
auto derived = make_shared<Derived>();
cout << "is_type<Base>(base) = " << (is_type<Base>(base) ? "true" : "false") << endl;
cout << "is_type<Derived>(base) = " << (is_type<Derived>(base) ? "true" : "false") << endl;
cout << "is_type<Base>(derived) = " << (is_type<Base>(derived) ? "true" : "false") << endl;
cout << "is_type<Derived>(derived) = " << (is_type<Derived>(derived) ? "true" : "false") << endl;
return 0;
}
Es gibt erwartet als das folgende Ergebnis:
is_type<Base>(base) = true
is_type<Derived>(base) = false
is_type<Base>(derived) = false
is_type<Derived>(derived) = true
Während dieses großen ist den statischen Typen eines Objekts abzurufen, wie kann diese behoben werden, wenn ich wollte is_type<Base>(derived)
true
anstelle von false
zurückgeben, so dass ich Klassenvererbung effektiv überprüfen kann? Ist das in C++ möglich?
Warum Sie das alle virtuellen Gitter brauchen, wenn Sie einfach 'std :: is_base_of' verwenden kann? – SergeyA
Nun, ich wusste nicht, 'std :: is_base_of', das sieht in der Tat sehr nützlich aus, aber dann die Frage ist, benötigt diese Funktion RTTI? – Deathicon
@Deathicon Nein. Es handelt sich um eine Typeigenschaft, die zur Kompilierzeit ausgewertet wird. – Rakete1111