Something like a nested mutex, but more general?

I am working on a project where the file should be saved after performing some operations on member objects of the class. Sometimes we want to save a file after one operation, sometimes we do not need to save it until a series of operations is completed.

My idea is to use a class that basically works like a recursive mutex. Except that instead of locking and unlocking the mutex, I want the class to call the method (in this case, save the file) when the last instance of the class on the stack falls out of scope.

Implementing a class that does this is not a problem, but it seems like a general problem that I simply cannot find in Boost or STL. Is there an existing standard solution to this problem, or do I need to flip my own class to do this? If so, is my approach correct, or is there a better way to solve the problem?

Below is a simple implementation of the behavior I'm looking for. He will print only "Hello World!". twice though DoItOnce () is called 11 times. I would like to use something like GenericGuard, pulling it out of a recognized standard, and not sticking to my own implementation in the code base. Is it possible?

#include <iostream>

void Noop (void) { }
void HelloWorld (void) { std::cout << "Hello World!" << std::endl; }

// This is what I imagine a generic implementation would look like...
template <void (*InitFunc)(), void (*DestructFunc)()>
class GenericGuard
{
  int & _i;
  public:
  GenericGuard (int & i) : _i(i) { if (_i++ == 0) { InitFunc(); } }
  ~GenericGuard () { if (--_i == 0) { DestructFunc(); } }
};

int HelloWorldCounter; // Use a factory class in real-world?

typedef GenericGuard<Noop, HelloWorld> HelloWorldGuard;

void DoSomethingOnce (void) 
{
  HelloWorldGuard G (HelloWorldCounter);
  // Do something
}

void DoItTenTimes (void)
{
  HelloWorldGuard G (HelloWorldCounter);
  for (int i = 0; i < 10; ++i)
  {
    DoSomethingOnce();
  }
}

int main (void)
{
  DoSomethingOnce();

  DoItTenTimes();

  return 0;
}
+4
source share
2 answers

shared_ptr .

:

#include <memory>
#include <iostream>

void    HelloWorld(void *) { std::cout << "Hello World!" << std::endl; }

class   factory
{
public:
  static std::shared_ptr<void> get_instance()
  {
    static std::weak_ptr<void>   ref;
    if (ref.expired())
      {
        std::shared_ptr<void>    sp{nullptr, HelloWorld};
        ref = sp;
        return sp;
      }
    return ref.lock();
  }

};

void DoSomethingOnce (void)
{
  std::shared_ptr<void>  G = factory::get_instance();
  // Do something
}

void DoItTenTimes (void)
{
  std::shared_ptr<void>  G = factory::get_instance();
  for (int i = 0; i < 10; ++i)
    {
      DoSomethingOnce();
    }
}

int     main(void)
{
  DoSomethingOnce();

  DoItTenTimes();

  return 0;
}
+3

, , -, : [1].

, ,

  • ( Do/Undo)

    • ( , , );
  • ;

  • ( , , ).

. , , . , , Unit-Of-Work ( , ), "", .


, , , , . (, , ?), , , . "" , . , , , .

, - Sean Parent ++. , , , "" , .


[1] , () .

0

Source: https://habr.com/ru/post/1545852/


All Articles