Call overriding class methods as chains in C ++

Several times I felt the need to define class methods that are called in the same way as constructors or destructors.

A specific example: in the program I had a very complex network of nodes of different types, which depended on each other very irregularly (the network did not resemble a tree at all). When a node needed to be destroyed, he began a complex chain of destruction on the network. Like the web is torn, but harder.

During the execution of this chain, control returned to the initiator's methods (or one of the intermediate elements in the chain), so the actual destruction should have happened when the chain was settled, and therefore I could not use destructors for this purpose. However, according to the class hierarchy of my nodes, I needed a "destructor similar", i.e. The staircase way to call my non-destructive function before destruction (for the same reasons why the so-called actual destructor is also called this way, every step in the class hierarchy should have contributed differently to the chain).

I finished coding the stairs manually. Namely, the nodeBase class has a method called "preDestroyNodeBase", which does its job and calls the virtual method "preDestroyNode", etc. To the sheet (I know that it looks like a constructor, but it was - relatively - more elegant in this way, since you can just call "preDestroy" from the base class).

You can imagine how error-prone this approach is, not to mention ugliness. Is there a cleaner way to emulate a constructor method or a call method destructor? Some kind of magical magic or even magic! Since manual coding is too error prone even for one programmer, so I can’t imagine how this manifests itself for library clients.

, , . , , , .

!

0
3

, , 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 preDestroy\n\n";

        Foo::PreDestroy();
    }
}

class MostDerived : public Bar
{
    public:
    void PreDestroy()
    {
        cout << "MostDerived preDestroy\n\n";

        Bar::PreDestroy();
    }
}

int main() 
{
    MostDerived testObj;

    testObj.PreDestroy();
}

:

MostDerived preDestroy

preDestroy

Foo preDestroy

+2

, , , ; , ( ).

. ( ++ 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;
}

node, - node, node, node, , .

0

You can use the visitor template to go through the node schedule (suppose you are talking about a schedule), and let the nodes put themselves in a sort of “be deleted” list (if necessary) that is held by the client object. In the second iteration, you can go through these elements of the list and call them the “kill” method, which in turn performs the final cleanup. This approach should have all of your nodes supporting the visitor pattern and containing this destroy method.

0
source

All Articles