我正在开发一个项目,在对类的成员对象执行某些操作后必须保存文件。有时我们想在一次操作后保存文件,有时我们需要在执行一批操作之后才保存它。
我的想法是使用一个基本上像递归互斥体一样工作的类。除了锁定和解锁互斥锁之外,我希望类在堆栈中最后一个类的实例超出范围时调用方法(在这种情况下,保存文件)。
实现一个执行此操作的类不是问题,但这感觉就像我在Boost或STL中找不到的一般问题。是否有预先存在的标准解决方案来解决这个问题,或者我是否需要自己的类来完成它?如果是这样,我的方法是正确的,还是有更好的方法来解决问题?
以下是我正在寻找的行为的简单实现。它只会打印“Hello World!”即使DoItOnce()被调用了11次也是两次。我希望使用像GenericGuard
这样的东西,从公认的标准中提取它,而不是在代码库中坚持我自己的实现。这可能吗?
#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;
}
答案 0 :(得分:3)
您可以将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;
}
答案 1 :(得分:0)
您之后的模式似乎确实是众所周知的:您正在寻找交易 [1] 中的分组操作。
我脑海中出现的相关模式是
命令模式(使用着名的Do / Undo示例)
工作单位模式;这使您可以对待处理的编辑进行分组并将其作为一个组应用
软件事务内存(专注于操作的真实原子性,例如异常安全)。
不,我不是一个坚定的模式倡导者,但我喜欢它让你谈论事物的概念:所以,你真正想要的是工作单位(可能是简单的分组命令),你想要一个&#34;交易&#34;在破坏时自动应用更改。
根据您的实际应用,可能会坚持使用您现在看到的可变对象方法,并偶尔序列化它。如果应用程序域变得稍微有点兴趣(例如,使用线程,撤消和/或版本控制?),当您移动到文档模型时,您会很快发现生活变得更加简单 不可变节点。这样可以便宜地编辑&#34;简单地替换节点就是一个复杂的对象图。即使在线程环境中,不可变的节点也可以安全地共享它们。
与您的问题相关的认为是Sean Parent的Seasoning C++ talk。虽然这侧重于如何组织您的文档模型,但我觉得它可能非常有见地,并且可能会给您带来突破性的#34;改变观点以使问题再次变得简单。[1] 在这种情况下根本不需要是原子的,尽管它们可能(需要)在您的应用程序域中。