考虑一个填充缓冲区的典型函数:
const char* fillMyBuffer( const char* buf, int size );
假设这个函数用一些有用的数据填充缓冲区,我想在调用后几乎立即使用这些数据,然后我想摆脱缓冲区。
一种有效的方法是在堆栈上分配:
doStuff();
{
char myBuf[BUF_LEN];
const char* pBuf = fillMyBuffer( myBuf, BUF_LEN );
processBuffer( pBuf );
}
doOtherStuff();
所以这对我的库来说很棒,因为缓冲区是在堆栈上分配的——基本上没有分配、使用和丢弃的成本。它持续包含大括号的整个范围。
但我有一个图书馆,我一直在做这种模式。我想稍微自动化一下。理想情况下,我想要如下所示的代码:
doStuff();
{
// tricky - the returned buffer lasts the entire scope of the braces.
const char* pBuf = fillMyBufferLocal();
processBuffer( pBuf );
}
doOtherStuff();
但是如何实现呢?
我做了以下,这似乎有效,但我知道这违反了标准:
class localBuf
{
public:
operator char* () { return &mBuf[0]; }
char mBuf[BUF_LEN];
};
#define fillMyBufferLocal() fillMyBuffer( localBuf(), BUF_LEN );
实际上,缓冲区在包含大括号的整个生命周期中都在堆栈上持续存在。但是标准说对象只需要持续到函数返回。例如,从技术上讲,它就像我在函数内部的堆栈上分配缓冲区一样不安全。
有没有一种安全的方法来实现这一目标?