解决此问题的一种 C++“ish”方法是将缓冲区本身描述为“可简单复制”(C++11 术语,在 C++98 和 2003 中是“普通旧数据”的“POD”)结构,其中微观例外是它有一个私有构造函数来防止实例化。然后为该结构构造一个指针对象。这是一个带有这个想法的完整但微不足道的程序:
#include <cstdlib>
#include <cstring>
struct MyBuffer
{
int length;
char data[1];
private:
MyBuffer() {}
MyBuffer& operator =(MyBuffer& other) { return other; }
};
class MyBufferPointer
{
MyBuffer *bufptr_;
static std::size_t getsize(std::size_t array_size)
{
return sizeof (MyBuffer) + array_size * sizeof (char);
}
static MyBuffer *getbuf(std::size_t array_length)
{
std::size_t sz = getsize(array_length);
return static_cast<MyBuffer*>( malloc(sz) );
}
public:
MyBufferPointer() { bufptr_ = NULL; }
MyBufferPointer(std::size_t array_length)
{
bufptr_ = getbuf(array_length);
bufptr_->length = array_length;
}
MyBufferPointer(const MyBufferPointer &other)
{
const MyBuffer *op = other.bufptr_;
if (op == NULL)
{
bufptr_ = NULL;
}
else
{
bufptr_ = getbuf(op->length);
bufptr_->length = op->length;
std::size_t sz = op->length * sizeof op->data[0];
std::memmove( bufptr_->data, op->data, sz );
}
}
MyBufferPointer& operator =(const MyBufferPointer &other)
{
const MyBuffer *op = other.bufptr_;
if (op == NULL)
{
bufptr_ = NULL;
}
else
{
bufptr_ = getbuf(op->length);
bufptr_->length = op->length;
std::size_t sz = op->length * sizeof op->data[0];
std::memmove( bufptr_->data, op->data, sz );
}
return *this;
}
~MyBufferPointer() { if (bufptr_) free(bufptr_); }
std::size_t size() const
{
return bufptr_ ? bufptr_->length : 0;
}
// conventience operations for access to the data array:
char &operator [](std::size_t index) { return bufptr_->data[index]; }
char at(size_t index) const { return bufptr_->data[index]; }
MyBuffer* c_buffer() { return bufptr_; }
};
#include <iostream>
using namespace std;
int main()
{
MyBufferPointer bufp;
cout << "bufp().size() = " << bufp.size()
<< ", c_buffer=" << bufp.c_buffer() << endl;
bufp = MyBufferPointer(100);
cout << "bufp().size() = " << bufp.size()
<< ", c_buffer=" << bufp.c_buffer() << endl;
return 0;
}
MyBuffer 结构是 C 数据区域的布局,只有私有构造函数和赋值运算符声明以防止实例化或尝试复制(在 C 或 C++ 中,它们都不能正常工作。) MyBufferPointer 类将其封装为 C++样式 char[] 数组,重载 [] 运算符。
这仍然使用 malloc(),而不是新的。满足您提到的那些 C API 所需的内存映像需要可变长度结构,而您无法在 new 创建的标准 C++ 类中获得它。这只是提供了一个 C++ 包装器,用于在该类中提供一个结构创建点(在静态成员函数 getsize() 和 getbuf() 中);并保证在指针超出范围时删除缓冲区。您可以添加 resize()、to_string()、substring() 或任何您想要的方法。
在优化之后,性能应该与普通指针访问的 C 结构相同,因为方法是在类中声明的并且足够简单,可以内联。