C ++和压缩结构

时间:2015-06-20 16:52:38

标签: c++ class struct

我有数据库项目,我想从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();

但是我越看到这一点,我就越不喜欢它,因为没有真正的优势。

我缺少什么?

3 个答案:

答案 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参数传递,而不是作为函数的显式参数传递。