我使用訪問者模式來處理很多不同的AST問題,結果證明它工作得很好。例如,我正在使用它來檢查靜態類型。這在查找確切類型時效果很好,但它不適用於派生類。即如果我們有從Base
繼承的Derived
,詢問Derived
對象是否爲Base
失敗。使用訪客模式檢查派生類的類型?
考慮下面的C++代碼:
#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;
}
它輸出如預期以下結果:
is_type<Base>(base) = true
is_type<Derived>(base) = false
is_type<Base>(derived) = false
is_type<Derived>(derived) = true
雖然這是很大的檢索靜態類型的對象的,如何能這如果我想要is_type<Base>(derived)
返回true
而不是false
,以便我可以有效地檢查類繼承嗎?這在C++中可能嗎?
爲什麼你需要所有這些虛擬網,如果你可以簡單地用'的std :: is_base_of'? – SergeyA
嗯,我不知道'std :: is_base_of',看起來非常有用,但問題是,這個函數是否需要RTTI? – Deathicon
@Deathicon號這是一個類型特徵,在編譯時進行評估。 – Rakete1111