是否可以防止 RAII 样式的类被“匿名”实例化?
假设我有一个 RAII 风格的 C++ 类:
class StateSaver
{
public:
StateSaver(int i) { saveState(); }
~StateSaver() { restoreState(); }
};
...在我的代码中像这样使用:
void Manipulate()
{
StateSaver save(1);
// ...do stuff that modifies state
}
...目标是进入某个状态,做一些事情,然后在离开该范围时离开该状态。有没有办法让这个拼写错误不编译(或警告,或以某种方式抱怨,以便可以注意到错误)?
void Manipulate()
{
StateSaver(1); // ruh-roh, state saved and immediately restored!
// ...do stuff that modifies state
}
我不知道 C++ 本身有什么可以用来防止这种情况,但这并不意味着它不存在。如果 C++ 中没有任何内容,则特定于编译器的扩展是可以接受的。我主要对任何针对 gcc 和 msvc 的东西感兴趣(有一天 icc,欢迎其他编译器的想法,但不太可能有用),因此对它们中的任何一个的 hack 都会有用(当然,抽象成适当的 #ifdef'd 宏定义) 。
Suppose I have an RAII-style C++ class:
class StateSaver
{
public:
StateSaver(int i) { saveState(); }
~StateSaver() { restoreState(); }
};
...to be used like so in my code:
void Manipulate()
{
StateSaver save(1);
// ...do stuff that modifies state
}
...the goal being to enter some state, do stuff, then leave that state when I leave that scope. Is there a way to make this typo not compile (or warn, or somehow complain so that the mistake can be noticed)?
void Manipulate()
{
StateSaver(1); // ruh-roh, state saved and immediately restored!
// ...do stuff that modifies state
}
I'm not aware of anything in C++ itself which I could use to prevent this, but that doesn't mean it doesn't exist. If there isn't anything in C++, compiler-specific extensions would be acceptable. I'm primarily interested in anything targeting gcc and msvc (someday icc, ideas for other compilers welcome but less likely to be useful) so hacks for any of them would be useful (abstracted into appropriately #ifdef'd macro definitions, of course).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我不确定是否可以在编译时完成任何操作。对于运行时检查,您可以这样做:
这需要客户端编写:
如果不将临时变量绑定到标识符,则无法对临时变量执行相同的操作(此时它与自动变量没有什么不同)。
I'm not sure if anything can be done at compile-time. For a run-time check, you could do this:
Which requires the client to write:
and there's no way to do the same for a temporary without binding it to an identifier (at which point it's no different from an auto variable).
SaveMatrix save();
也没有定义对象。它声明了一个函数。您几乎无法阻止他人(或您自己,FTM)做他们不想做的事情。我唯一能想到的就是不写代码本身,而是写一个宏。
然而,这是相当难看的。 OTOH,它确实在编译时捕获了错误。
SaveMatrix save();
doesn't define an object either. It declares a function.There's very little you can do to prevent others (or yourself, FTM) from doing something else than they wanted to. The only thing I can think of is not writing the code itself, but writing a macro instead.
However, this is quite ugly. OTOH, it does catch the error at compile-time.
实际上,我必须从变体 Waldo 中通过多种方式调整我的解决方案发布了,但我最终得到的是一个宏化版本:
I actually had to tweak my solution in a bunch of ways from the variant Waldo posted, but what I eventually got to is a macro-ized version of:
该类永远无法判断它是被实例化为临时变量(SaveMatrix())还是变量(SaveMatrix save;)。我认为阻止程序员在没有堆栈或宏黑客的情况下这样做的最佳方法是在构造后强制调用成员函数,例如:
然后按如下方式工作:
The class can never tell if it was instantiated as a temporary (SaveMatrix()) or as a variable (SaveMatrix save;). I think the best way to stop the programmer doing that without stack or macro hacks is to force a member function call after construction, eg:
This then works as follows: