在C ++中将覆盖类方法作为链调用

时间:2012-01-19 14:21:53

标签: c++ function constructor

不止一次我觉得需要定义以类似于构造函数或析构函数的方式调用的类方法。

一个具体的例子是;在一个程序中,我有一个非常复杂的不同类型的节点网络,它们以非常不规则的方式相互依赖(网络根本不像一棵树)。当一个节点需要被销毁时,它会在网络中启动一个复杂的破坏链。就像蜘蛛网被撕裂一样,但更复杂。

在执行此链的过程中,控件返回到启动器的方法(或链中的一个中间元素),因此当链已经解决时必须进行实际的破坏,这就是为什么我不能为此目的使用析构函数。但是,沿着我的节点的类层次结构,我需要一个“类似析构函数”,即调用我的非破坏预破坏函数的梯形方式(完全相同的原因,为什么实际的析构函数也被称为这种方式,即,类层次结构中的每一步都需要以不同的方式为链做出贡献。)

我最终手工编写了梯子。也就是说,类nodeBase有一个名为“preDestroyNodeBase”的方法,它完成它的工作并调用虚方法“preDestroyNode”等等直到叶子(我知道,这样它看起来像一个构造函数,但它比较 - 更优雅这样,既然你可以调用最基类的“preDestroy”。

你可以想象这种方法是多么容易出错,更不用说丑陋了。是否有更简洁的方法来模拟构造函数或析构函数的调用方法?某种模板魔法甚至宏魔法!因为手动编码太容易出错,即使是单个程序员,所以我无法想象将这种行为暴露给库的客户端。

也许我错过了一个基本的编程概念,它废弃了对这些函数的需求。如果是这种情况,如果您指出如何处理节点网络示例,我会很高兴。

非常感谢!

3 个答案:

答案 0 :(得分:2)

当你声明一个虚函数时,它将调用该函数的派生最多的处理程序,然后从那里你有每个处理程序调用{​​{1}},并且调用将转到下一个派生的处理程序该功能,您可以再次呼叫NextMostDerivedClass::preDestroy,依此类推。这与虚拟析构函数所采用的路径相同,除了您不必使用析构函数手动调用任何内容,它是自动化的。如果您要将以下代码示例中的NextMostDerivedClass::preDestroy语句放入析构函数中,您可以看到与下面的示例相同的输出。

cout

输出应为:

MostDerived preDestroy

Bar preDestroy

Foo preDestroy

答案 1 :(得分:0)

我使用订阅机制,如果你想要一个指向另一个对象的指针,你还必须订阅它们的销毁事件;收到此类活动后,取消订阅您自己的活动,并清理您自己的结构(这可能会导致进一步的破坏)。

即。 (C ++ 1x语法简洁)

struct node {
    ~node() { for(auto i : subscribers) i->notify(this); }
    void subscribe(node *n) { subscribers.push_back(n); }
    void notify(node *n) { subscribers.remove(n); /* Handle other node being removed */ }

private:
    std::list<node *> subscribers;
}

要访问节点的数据成员,您需要通过扩展节点类本身,或者使用从实际包含数据的类继承的模板化节点类,使它们成为节点类的子对象。

答案 2 :(得分:0)

您可以使用访问者模式浏览节点图(我假设您正在讨论图表)并让节点将自己置于一种“待删除”列表中(如果需要)由访问者对象保持。在第二次迭代中,您可以浏览列表元素并在它们上调用一种“destroy”方法,然后进行最终清理。这种方法需要让所有节点都支持访问者模式并包含“destroy”方法。