禁止实例化为临时对象 (C++)
我喜欢在 C++ 中使用哨兵类,但我似乎有一种精神上的痛苦,导致重复编写如下错误:
{
MySentryClass(arg);
// ... other code
}
不用说,这会失败,因为哨兵在创建后立即死亡,而不是在作用域结束时死亡,如故意的。有没有某种方法可以防止 MySentryClass 被实例化为临时对象,从而使上述代码要么无法编译,要么至少在运行时中止并显示错误消息?
I like using sentry classes in c++, but I seem to have a mental affliction that results in repeatedly writing bugs like the following:
{
MySentryClass(arg);
// ... other code
}
Needless to say, this fails because the sentry dies immediately after creation, rather than at the end of the scope, as intended. Is there some way to prevent MySentryClass from being instantiated as a temporary, so that the above code either fails to compile, or at least aborts with an error message at runtime?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我想不出一种自动方法来检测您是否犯了这个错误。您始终可以创建一个扩展为正确内容的宏,并使用它来声明哨兵,而不是如果您继续错误地使用它。
然后使用
或在显示器上贴一张便利贴来提醒您。
I can't think of an automatic way to detect if you make this mistake or not. You could always create a macro that expands to the correct thing and use that to declare the sentry instead if you keep using it wrong.
and then use
or put a post-it on your monitor to remind you.
您唯一能做的就是将构造函数设为私有并通过辅助函数强制访问。这与最初的构造语法不太相似,并且不太可能出错。您也可以在堆上分配(仍然是浪费),但更容易发现。但是,如果您希望您的类是可构造的,您就无法阻止人们构造该类型的右值。
编辑:如果您知道 MySentryClass 总是带有参数,您可以禁止构造 AND 并只允许运算符=(参数)。这将迫使你做
你可以为它做某种方法链。
The only thing you could do is make the constructors private and force access through a helper function. This is far less similar than the initial construction syntax and less likely to be mistaken. You could also allocate on the heap (still a waste) but it's much easier to spot. However, if you want your class to be constructible, you can't stop people constructing rvalues of that type.
Edit: IF you know that MySentryClass always takes an argument, you could disallow construction AND and only allow operator=(arguments). This would force you to do
You could do some kind of method chain for it.
不,这个问题没有出路。要在堆栈上创建对象,您必须具有公共构造函数,如果您有公共构造函数,则可能会犯您所报告的错误。
No, there is no exit from this problem. To make objects on the stack, you have to have public constructors, and if you have public constructors, you can make the mistake you are reporting.
不确定您是否会喜欢这个解决方案,但解决方案很可能是
grep
:您可以做的另一件事是使用
sed
或perl
进行预处理您的源文件,将MySentryClass(
替换为\n#error MySentryClass using unavailablely\n
,这有望为您提供接近错误位置的行号。如何执行此操作取决于您的构建系统。Not sure you'll like this solution, but the solution may well be
grep
:Another thing you could do is use
sed
orperl
to preprocess your source file, replacingMySentryClass(
with\n#error MySentryClass used incorrectly\n
, which hopefully will give you a line number that's close to where the error is. How to do this depends on your build system.我认为 #define 是最好的方法。
但只是作为不使用 #define:
Main
Edited 的一个选项。现在效果更好了。
I think the #define is the best method.
But just as an option for not using #define:
Main
Edited. Now works better.
你试图做的事情在 C++ 中是完全合法的,我认为没有办法禁止它。
What you are trying to do is perfectly legal in C++ and I don't think there is a way to disallow it.