对于一个类Foo,有没有办法在不给它命名的情况下禁止构造它?
例如:
Foo("hi");
并且只有在你给它一个名字的情况下才允许它,就像下面这样?
Foo my_foo("hi");
第一个是语句的生命周期,第二个是封闭块的生命周期。在我的用例中,Foo
测量构造函数和析构函数之间的时间。因为我从来不引用局部变量,所以我经常忘记把它放进去,并且意外地改变了生命周期。相反,我希望得到一个编译时错误。
发布于 2012-10-31 22:08:15
来点小技巧怎么样?
class Foo
{
public:
Foo (const char*) {}
};
void Foo (float);
int main ()
{
Foo ("hello"); // error
class Foo a("hi"); // OK
return 1;
}
发布于 2012-11-01 07:00:50
这不会导致编译器错误,但会导致运行时错误。不是测量错误的时间,而是得到一个可能也是可以接受的异常。
要保护的任何构造函数都需要一个默认参数,在该参数上调用set(guard)
。
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;
};
其特点是:
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();
}
f2
、f3
和"hello"
的回归可能不是我们想要的。为了防止抛出,您可以允许副本的源是临时的,方法是将guard
重置为现在保护我们而不是副本的源。现在你也明白为什么我们使用上面的指针了--它让我们更灵活。
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;
};
f2
、f3
和return "hello"
的特征现在始终是// OK
。
发布于 2012-11-01 00:46:43
几年前,我为GNU C++编译器编写了a patch,它为这种情况添加了一个新的警告选项。这是在a Bugzilla item中跟踪的。
不幸的是,GCC Bugzilla是一个埋葬之地,深思熟虑的包含补丁的功能建议将走向死亡。:)
这样做的动机是希望准确地捕获代码中这个问题的主题类型的bug,这些代码使用本地对象作为锁定和解锁的小工具,测量执行时间等。
https://stackoverflow.com/questions/13159739
复制相似问题