gpt4 book ai didi

c++ - 在树节点上实现执行操作的最佳方式,最好不使用访问者

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:36:07 25 4
gpt4 key购买 nike

我有一个用户界面,左侧是 TreeView ,右侧是查看器(有点像电子邮件客户端)。右侧的查看器显示我在左侧树中选择的任何内容的详细信息。

用户界面有“添加”、“编辑”和“删除”按钮。这些按钮的行为因树中选择的“节点”而异。

如果我选择了一个特定类型的节点,并且用户单击“编辑”,那么我需要为该特定类型的节点打开适当的编辑对话框,其中包含该节点的详细信息。

现在,有很多不同类型的节点,实现访问者类感觉有点困惑(目前我的访问者有大约 48 个条目......)。它确实工作得很好 - 基本上用于编辑一个类似 OpenEditDialog 类的东西,它继承了访问者,并打开适当的编辑对话框:

abstractTreeNode->accept(OpenEditDialog());

问题是我必须为我想在节点上执行的每个“ Action ”实现抽象访问者类,出于某种原因我不禁认为我错过了一个技巧。

另一种方法可能是在节点本身中实现功能:

abstractTreeNode->openEditDialog();

我在这里对节点进行了一些排序,所以也许这样更好:

abstractTreeNode->editClickedEvent();

不过我不禁认为这是在污染节点。

我确实想到了第三种方法,但我还没有考虑那么多。我可以有一个模板化的包装类,它被添加到树中,而不是允许我调用自由函数来执行任何操作,所以我猜它充当节点和接口(interface)之间的过渡:

(伪代码只是为了提供一个想法):

template <class T>
TreeNode(T &modelNode)
{
m_modelNode = modelNode;
}

template <>
void TreeNode<AreaNode>::editClickedEvent()
{
openEditDialog(m_modelNode); // Called with concrete AreaNode
}

template <>
void TreeNode<LocationNode>::editClickedEvent()
{
openEditDialog(m_modelNode); // Called with concrete LocationNode
}

等..

因此,这有效地扩展了节点,但使用访问者的方式不同,而且看起来更简洁一些。

现在,在我继续尝试使用其中一种方法之前,我认为征求一些意见是明智的。

谢谢!我希望所有这些都有意义..

编辑:

我模拟了模板化包装器的想法..

class INode
{
public:
virtual ~INode() {}
virtual void foo() = 0;
};

class AreaNode : public INode
{
public:
AreaNode() {}
virtual ~AreaNode() {}
void foo() { printf("AreaNode::foo\r\n"); }
};

class RoleNode : public INode
{
public:
RoleNode() {}
virtual ~RoleNode() {}
void foo() { printf("RoleNode::foo\r\n"); }
};

class ITreeNode
{
public:
virtual ~ITreeNode() {}
virtual void bar() = 0;
virtual void foo() = 0;
};

template <class T>
class MainViewTreeNode : public ITreeNode
{
public:
MainViewTreeNode() : m_node() {}
virtual ~MainViewTreeNode() {}
void bar() {}
void foo() { m_node.foo(); }
protected:
T m_node;
};

template <>
void MainViewTreeNode<AreaNode>::bar()
{
printf("MainViewTreeNode<AreaNode>::bar\r\n");
}

template <>
void MainViewTreeNode<RoleNode>::bar()
{
printf("MainViewTreeNode<RoleNode>::bar\r\n");
}

int _tmain(int argc, _TCHAR* argv[])
{
MainViewTreeNode<RoleNode> role;
MainViewTreeNode<AreaNode> area;

std::list<ITreeNode*> nodes;
nodes.push_back(&role);
nodes.push_back(&area);

std::list<ITreeNode*>::iterator it = nodes.begin();

for (; it != nodes.end(); ++it)
{
(*it)->foo();
(*it)->bar();
}

getchar();
return 0;
}

谢谢。

最佳答案

当您有许多操作少数类型时,访问者很有用。如果您有很多类型,但操作很少,请使用普通的多态性。

关于c++ - 在树节点上实现执行操作的最佳方式,最好不使用访问者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3330399/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com