在C++中将overriden类方法作为链调用
Calling overriden class methods as a chain in C++
不止一次,我觉得有必要定义以类似于构造函数或析构函数的方式调用的类方法。
一个具体的例子是:;在一个程序中,我有一个由不同类型的节点组成的非常复杂的网络,这些节点以非常不规则的方式相互依赖(这个网络根本不像树)。当一个节点需要被破坏时,它会在网络中启动一系列复杂的破坏。就像一张被撕裂的蜘蛛网,但更复杂。
在执行这个链的过程中,控制权又回到了启动器(或链中的一个中间元素)的方法上,因此实际的销毁必须在链稳定下来时进行,这就是为什么我不能为此目的使用析构函数。然而,沿着我的节点的类层次结构,我需要一个"类似析构函数"的方法,即调用我的非破坏性预析构函数的梯形方法(原因完全相同,为什么实际的析构函数也以这种方式调用,即类层次结构中的每一步都需要以不同的方式对链做出贡献)。
我最终用手给梯子编码。也就是说,类nodeBase有一个名为"preDestroyNodeBase"的方法,它完成自己的工作,并调用虚拟方法"preDestroyNode"等等,直到叶子(我知道,这样它看起来像一个构造函数,但相对而言,它更优雅,因为你可以调用最基类的"preDestination")。
你可以想象这种方法是多么容易出错,更不用说丑陋了。有没有一种更干净的方法来模拟构造函数或析构函数调用方法?某种模板魔术,甚至宏魔术!因为手工编码太容易出错,即使对于单个程序员来说也是如此,所以我无法想象将这种行为暴露给库的客户端。
也许我错过了一个基本的编程概念,它抛弃了对此类函数的需求。如果是这样的话,如果你能指出如何处理节点网络的例子,我会很高兴。
非常感谢!
当您声明一个虚拟函数时,它将调用该函数的最派生处理程序,然后从那里开始,每个处理程序都调用NextMostDerivedClass::preDestroy
,调用将转到该函数的下一个最派生的处理程序,您可以再次调用NextMostDerivedClass::preDestroy
,依此类推。这与虚拟析构函数所采用的路径相同,除了你不必用析构函数手动调用任何东西之外,它是自动的。如果将以下代码示例中的cout
语句放入析构函数中,则可以看到与以下示例提供的输出相同的输出。
#include <iostream.h>
class Foo
{
public:
virtual void PreDestroy()
{
cout << "Foo preDestroy";
}
}
class Bar : public Foo
{
public:
void PreDestroy()
{
cout << "Bar preDestroynn";
Foo::PreDestroy();
}
}
class MostDerived : public Bar
{
public:
void PreDestroy()
{
cout << "MostDerived preDestroynn";
Bar::PreDestroy();
}
}
int main()
{
MostDerived testObj;
testObj.PreDestroy();
}
输出应为:
MostDerived预销毁
条形码预销毁
Foo预销毁
您可以使用访问者模式浏览节点图(我假设您谈论的是一个图),并让节点将自己放入访问者对象持有的一种"待删除"列表(如果需要)中。在第二次迭代中,您可以遍历列表元素,并对它们调用一种"destroy"方法,该方法反过来进行最终清理。这种方法需要让所有节点都支持访问者模式并包含"destroy"方法。
我会使用订阅机制,如果你想让a持有指向另一个对象的指针,你还必须订阅它们的销毁事件;收到此类事件后,取消他们对您自己事件的订阅,并清理您自己的结构(这可能会导致进一步的破坏)。
即(为简洁起见,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;
}
要访问节点的数据成员,需要通过扩展节点类本身或使用从实际包含数据的类继承的模板化节点类,使它们成为节点类的子对象。
- 使用用户定义的参数调用future/async并调用类方法
- 有没有办法从同一类中的函子调用类方法?
- 是否可以基于类模板的参数调用类方法和全局方法
- 为什么从 DLL 调用类方法需要虚拟说明符?
- 通过该类中定义的指针调用类方法时的语法
- 从另一个类调用类方法
- 如何在不创建实例的情况下调用类方法
- 在不使用对象的情况下调用类方法
- 通过循环std::map调用类方法
- 我必须创建一个对象来调用类方法吗?或者我可以只键入类名吗
- 在main中调用类方法,更改不会在类方法之外保留?
- C++ - 调用<类方法没有匹配函数>
- C++:从非类函数调用类方法
- 通过包装对象上的函数指针调用类方法出错
- 在同一个方法中调用类方法
- 使用std::string调用类方法
- 在自身上调用类方法
- c++从类内调用类方法
- 使用Boost基本截止时间计时器来调用类方法
- 将lambdas传递给std::线程并调用类方法