我有一個清單:std::list<MyType*>*
MyType是一個抽象類,我想處理每個滿足條件的串列項,但是串列可以包含也是型別的元素,std::list我也想處理它們。它可以有多個深度。
我更喜歡以迭代方式處理它,但遞回解決方案也很好。不幸的是,我還不知道該怎么做。
例如,一個串列如下所示:
Root std::list elements:
Type_A -> int
Type_B -> std::list
Type_C -> int
Type_B -> std::list
Type_A -> int
Type_C -> int
Type_A -> int
Type_A -> int
Type_D -> std::list
Type_A -> int
Type_A -> int
Type_A -> int
如您所見Type_A,是標量型別,沒問題。
Type_B也是一個串列,我要處理Type_B元素。
Type_B也可以有std::list物品,我也必須處理它們,等等。
代碼示例:
void MyFunc(std::list<MyType*>* &statements)
{
std::list<MyType*>::iterator it;
for (it = statements->begin(); it != statements->end(); it)
{
if ((*it)->GetType() == _expectedType) // this type also has a list
{
std::list<MyType*>* statementList = dynamic_cast<ExpectedType*>(*it)->GetStatementList();
std::list<Statement*>::iterator it2 = statementList->begin();
// do some iterative or recursive process
}
}
uj5u.com熱心網友回復:
您可以使用訪問者模式
class Type_A;
class Type_B;
class Type_C;
class Type_D;
struct MyType_Visitor {
virtual void visit(Type_A & a) = 0;
virtual void visit(Type_B & b) = 0;
virtual void visit(Type_C & c) = 0;
virtual void visit(Type_D & d) = 0;
};
class MyType {
public:
virtual ~MyType() = default;
virtual void accept(MyType_Visitor & visitor) = 0;
// existing members
}
class Type_A : public MyType {
public:
void accept(MyType_Visitor & visitor) override {
visitor.visit(*this); // calls void visit(Type_A & a)
}
// existing members
};
class Type_B : public MyType {
std::list<MyType *> children;
public:
void accept(MyType_Visitor & visitor) override {
visitor.visit(*this); // calls void visit(Type_B & b)
for (MyType * child : children) {
child->accept(visitor); // also visit all the children
}
}
// existing members
};
class Type_C : public MyType {
public:
void accept(MyType_Visitor & visitor) override {
visitor.visit(*this); // calls void visit(Type_C & c)
}
// existing members
};
class Type_D : public MyType {
std::list<MyType *> other_things;
public:
void accept(MyType_Visitor & visitor) override {
visitor.visit(*this); // calls void visit(Type_D & d)
for (MyType * thing : other_things) {
thing->accept(visitor); // also visit all the children
}
}
// existing members
};
然后,這允許您為不同的情況定義不同的行為,例如
class PrintVisitor : public MyType_Visitor {
void visit(Type_A & a) override {
std::cout << "Type_A -> int" << std::endl;
}
void visit(Type_B & b) override {
std::cout << "Type_B -> std::list" << std::endl;
}
void visit(Type_C & c) override {
std::cout << "Type_C -> int" << std::endl;
}
void visit(Type_D & d) override {
std::cout << "Type_D -> std::list" << std::endl;
}
}
class MeetsConditionVisitor : public MyType_Visitor {
void visit(Type_A &) override { /* only care about B */ }
void visit(Type_B & b) override {
if (/* b specific something */) {
// stuff
}
}
void visit(Type_C &) override { /* only care about B */ }
void visit(Type_D &) override { /* only care about B */ }
}
uj5u.com熱心網友回復:
如果任何子類都可能有子類,那么您可以有一個虛擬成員函式來公開它。
class MyType {
public:
virtual ~MyType() = default;
virtual const std::list<MyType*> & children() {
// default -> no children
static const std::list<MyType*> empty;
return empty;
}
// existing members
}
class Type_B : public MyType {
std::list<MyType*> stuff;
public:
const std::list<MyType*> & children() override { return stuff; }
}
class Type_D : public MyType {
std::list<MyType*> things;
public:
const std::list<MyType*> & children() override { return things; }
}
void MyFunc(const std::list<MyType*> & statements)
{
for (auto * item : statements)
{
// stuff before visiting children
MyFunc(item->children());
// other stuff after visiting children
}
}
uj5u.com熱心網友回復:
我想您可以使用多型性并讓樹中的每個節點自行處理,如下所示:
class MyType
{
virtual void visit(Environment& env) const = 0;
};
class MyListType : public MyType
{
std::list<std::unique_ptr<MyType>> _elements;
void visit(Environment& env) const override
{
for (const auto& node : _elements)
node->visit(env);
}
};
class MyLeafType : public MyType
{
void visit(Environment& env) const override
{
// whatever
}
};
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/445339.html
上一篇:如何在C 中推斷回傳型別
