c – 构造函数中的RAII和异常

想象一下,我有一份工作要做,可以通过三种不同的方式来完成:缓慢而痛苦,但却是安全的方式;鉴于你有资源1,适度痛苦的方式;以及一种快速简便的方法,它需要Resource1和Resource2.现在,这些资源是宝贵的,所以我将它们包装成RAII实现ResNHolders并写下这样的东西:
void DoTheJob(Logger& log/*,some other params */) {
    try {
        Res1Holder r1(/* arguments for creating resource #1 */);
        try {
            Res2Holder r2(/* arguments */);
            DoTheJobQuicklyAndEasily(log,r1,r2);
        }
        catch (Res2InitializationException& e) {
            log.log("Can't obtain resource 2,that'll slowdown us a bit");
            DoTheJobWithModerateSuffering(log,r1);
        }
    }
    catch (Res1InitializationException& e) {
        log.log("Can't obtain resource 1,using fallback");
        DoTheJobTheSlowAndPainfulWay(log);
    }
}

“DoTheJobXxx()”引用了Logger / ResNHolder,因为它们是不可复制的.我这样做太笨拙了吗?有没有其他聪明的方法来构建函数

解决方法

我认为你的代码会很好,但这里有一个可以考虑的替代方案:
void DoTheJob(Logger &log/*,args*/)
{
    std::unique_ptr<Res1Holder> r1 = acquireRes1(/*args*/);
    if (!r1) {
        log.log("Can't acquire resource 1,using fallback");
        DoTheJobTheSlowAndPainfulWay(log);
        return;
    }
    std::unique_ptr<Res2Holder> r2 = acquireRes2(/*args*/);
    if (!r2) {
        log.log("Can't acquire resource 2,that'll slow us down a bit.");
        DoTheJobWithModerateSuffering(log,*r1);
        return;
    }
    DoTheJobQuicklyAndEasily(log,*r1,*r2);
}

当资源无法初始化时,acquireRes函数返回null unique_ptr:

std::unique_ptr<Res1Holder> acquireRes1()
{
  try {
    return std::unique_ptr<Res1Holder>(new Res1Holder());
  }
  catch (Res1InitializationException& e) {
    return std::unique_ptr<Res1Holder>();
  }
}

std::unique_ptr<Res2Holder> acquireRes2()
{
  try {
    return std::unique_ptr<Res2Holder>(new Res2Holder());
  }
  catch (Res2InitializationException& e) {
    return std::unique_ptr<Res2Holder>();
  }
}

相关文章

对象的传值与返回说起函数,就不免要谈谈函数的参数和返回值...
从实现装饰者模式中思考C++指针和引用的选择最近在看...
关于vtordisp知多少?我相信不少人看到这篇文章,多半是来自...
那些陌生的C++关键字学过程序语言的人相信对关键字并...
命令行下的树形打印最近在处理代码分析问题时,需要将代码的...
虚函数与虚继承寻踪封装、继承、多态是面向对象语言的三大特...