首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何禁止临时文件

如何禁止临时文件
EN

Stack Overflow用户
提问于 2012-10-31 22:00:39
回答 7查看 4.3K关注 0票数 108

对于一个类Foo,有没有办法在不给它命名的情况下禁止构造它?

例如:

代码语言:javascript
复制
Foo("hi");

并且只有在你给它一个名字的情况下才允许它,就像下面这样?

代码语言:javascript
复制
Foo my_foo("hi");

第一个是语句的生命周期,第二个是封闭块的生命周期。在我的用例中,Foo测量构造函数和析构函数之间的时间。因为我从来不引用局部变量,所以我经常忘记把它放进去,并且意外地改变了生命周期。相反,我希望得到一个编译时错误。

EN

回答 7

Stack Overflow用户

发布于 2012-10-31 22:08:15

来点小技巧怎么样?

代码语言:javascript
复制
class Foo
{
    public:
        Foo (const char*) {}
};

void Foo (float);


int main ()
{
    Foo ("hello"); // error
    class Foo a("hi"); // OK
    return 1;
}
票数 71
EN

Stack Overflow用户

发布于 2012-11-01 07:00:50

这不会导致编译器错误,但会导致运行时错误。不是测量错误的时间,而是得到一个可能也是可以接受的异常。

要保护的任何构造函数都需要一个默认参数,在该参数上调用set(guard)

代码语言:javascript
复制
struct Guard {
  Guard()
    :guardflagp()
  { }

  ~Guard() {
    assert(guardflagp && "Forgot to call guard?");
    *guardflagp = 0;
  }

  void *set(Guard const *&guardflag) {
    if(guardflagp) {
      *guardflagp = 0;
    }

    guardflagp = &guardflag;
    *guardflagp = this;
  }

private:
  Guard const **guardflagp;
};

class Foo {
public:
  Foo(const char *arg1, Guard &&g = Guard()) 
    :guard()
  { g.set(guard); }

  ~Foo() {
    assert(!guard && "A Foo object cannot be temporary!");
  }

private:
  mutable Guard const *guard;
}; 

其特点是:

代码语言:javascript
复制
Foo f() {
  // OK (no temporary)
  Foo f1("hello");

  // may throw (may introduce a temporary on behalf of the compiler)
  Foo f2 = "hello";

  // may throw (introduces a temporary that may be optimized away
  Foo f3 = Foo("hello");

  // OK (no temporary)
  Foo f4{"hello"};

  // OK (no temporary)
  Foo f = { "hello" };

  // always throws
  Foo("hello");

  // OK (normal copy)
  return f;

  // may throw (may introduce a temporary on behalf of the compiler)
  return "hello";

  // OK (initialized temporary lives longer than its initializers)
  return { "hello" };
}

int main() {
  // OK (it's f that created the temporary in its body)
  f();

  // OK (normal copy)
  Foo g1(f());

  // OK (normal copy)
  Foo g2 = f();
}

f2f3"hello"的回归可能不是我们想要的。为了防止抛出,您可以允许副本的源是临时的,方法是将guard重置为现在保护我们而不是副本的源。现在你也明白为什么我们使用上面的指针了--它让我们更灵活。

代码语言:javascript
复制
class Foo {
public:
  Foo(const char *arg1, Guard &&g = Guard()) 
    :guard()
  { g.set(guard); }

  Foo(Foo &&other)
    :guard(other.guard)
  {
    if(guard) {
      guard->set(guard);
    }
  }

  Foo(const Foo& other)
    :guard(other.guard)
  {
    if(guard) {
      guard->set(guard);
    }
  }

  ~Foo() {
    assert(!guard && "A Foo object cannot be temporary!");
  }

private:
  mutable Guard const *guard;
}; 

f2f3return "hello"的特征现在始终是// OK

票数 25
EN

Stack Overflow用户

发布于 2012-11-01 00:46:43

几年前,我为GNU C++编译器编写了a patch,它为这种情况添加了一个新的警告选项。这是在a Bugzilla item中跟踪的。

不幸的是,GCC Bugzilla是一个埋葬之地,深思熟虑的包含补丁的功能建议将走向死亡。:)

这样做的动机是希望准确地捕获代码中这个问题的主题类型的bug,这些代码使用本地对象作为锁定和解锁的小工具,测量执行时间等。

票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13159739

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档