我有数据库项目,我想从C转移到C ++。在这个C项目中,我有很多小的打包结构,我直接写入文件或从mmaped文件中读取 - 例如直接来自内存地址。
我需要类内存表示,与我使用普通的旧C结构完全相同。我相信这称为POD或C ++标准布局。
我可以通过以下几种方式继续:
我可以上课,但我担心如果我向这个结构添加方法,可能会改变内部结构。
如果我将一个结构包装到类中,我将需要一直创建/销毁类,以及结构。
如果我做C - OO风格,我需要提供指向每个功能的指针,例如
static const char *Pair::getKey(const void *mem);
我也可以将结构化为字段并执行类似的操作
void Pair::setMem(const void *mem);
const char *Pair::getKey();
但是我越看到这一点,我就越不喜欢它,因为没有真正的优势。
我缺少什么?
答案 0 :(得分:5)
如果我向这个结构添加方法,可能会改变内部结构。
那是错的;为了满足您的需求,您希望将结构保持为POD,基本上您不需要:
(还有一些额外的限制(参见C ++11§9¶6-10),但它们在你的情况下并不是特别相关)
“POD”事情意味着两件事:
你的班级是“标准布局”,大致意思是“以明确的方式布局,与C会做的一样”(评估你的主要关注点);
添加方法不应该破坏东西,因为它们不是虚拟的,因此它们被翻译为自由函数,它将指向对象的指针作为隐藏参数,并且不需要修改原始C布局。
static
方法只是具有不同范围的自由函数,因此通常它们不是问题。
您的课程可以memcpy
自由复制而不会破坏,如果您直接从文件中读取(mmap
或{{1},这可能就是您想要的}});
这是由构造函数的“无关紧要”(即如果它们被跳过,对象没有发生任何不良事件)以及缺少虚拟成员,这意味着您没有冒险覆盖过时的vptr一个从文件中读取。
答案 1 :(得分:3)
C ++ 11有一个称为标准布局的特定概念,它基本上意味着对于满足标准布局要求的类,它保证类将在内存中布置与C相同。要求是:
所以你可以在你的课程中添加方法,只要你小心。请参阅http://en.cppreference.com/w/cpp/concept/StandardLayoutType。
答案 2 :(得分:1)
如果我向这个结构添加方法,可能会改变内部结构。
这不太可能,至少不会改变编译器(从C到C ++)。您可以添加方法,只要它们不是构造函数,析构函数,赋值运算符或虚函数,并且内存布局保证不会更改。
有关详细信息,请参阅Structure of a C++ Object in Memory Vs a Struct
如果我将结构包装到类中,我将需要一直创建/销毁类。
这与始终创建和销毁结构完全相同。 C ++中的类实例化包括内存分配和对构造函数的调用。您对分配的控制与对结构的控制相同,并且您可以控制构造函数中的所有代码(包括根本没有代码的选项)。
编写C代码并使用C ++编译器构建它是完全合法的。也可以编写C ++代码(在一些限制下),编译与C代码完全相同的二进制文件。使用类/结构成员获取的是一种(可以说是)更清晰的语法,并暗示了this
指针。例如:
// C
ret = CallMyStructMethodX(pMyStruct, param1, param2);
// C++
ret = pMyStruct->CallMethodX(param1, param2);
这两行代码是相同的。仅 的区别在于,在后一种情况下,结构指针由隐含的this
参数传递,而不是作为函数的显式参数传递。