可以检测未捕获的堆栈分配对象吗?

时间:2014-07-08 00:39:25

标签: c++ raii

是否有可能以任何方式(静态分析)阻止或检测以下错误,其中堆栈分配的对象未被捕获并超出其构造的同一行的范围?

Resource  resourceA, resourceB;

void someFunction()
{
    ScopedResourceBinder resourceBindA( resourceA );
    ScopedResourceBinder( resourceB ); // <--- BUG
}

第一个ScopedResourceBinder是正确的,但第二个没有做任何事情,因为它在“绑定”之后立即“解除绑定”(假设说)。

这显然是一个程序员错误,但我现在已经调试了几次(几个小时的几个小时)并且很难发现。一旦你看到它,你会认为“这是一个愚蠢的啊”,但在实践中,很容易犯错误,编译器无法控制......或者是它?

背景信息:我使用的是一个大量使用RAII类来推送弹出状态的库,例如OpenGL资源。使用范围管理绑定是手动调用bind()/ unbind()函数的一个重大改进,但是这里列出的潜在错误会出现这种新模式。

2 个答案:

答案 0 :(得分:2)

ScopedResourceBinder( resourceB );ScopedResourceBinder resourceB;相同,即它声明一个名为resourceB的命名变量,调用ScopedResourceBinder的默认构造函数。

这一直持续到函数结束,但它仍然是一个bug,因为它没有执行绑定到变量resourceB的意图。

为防止出现这种特殊情况,您可以确保ScopedResourceBinder没有默认构造函数。

答案 1 :(得分:0)

在一般的编码实践中,我们应该在类定义本身中明确表达我们的意图。

例如:

如果我们想要单例类,那么所有构造函数都应该是私有的。

如果我们想用一些变量构造一个对象,那么只有所需的构造函数应该公开公开,所有应该被称为私有。

通过这种方式,我们只能在编译时标记所有错误的用法。