代码之家  ›  专栏  ›  技术社区  ›  Methos

C与VC++结构的比较

  •  1
  • Methos  · 技术社区  · 15 年前

    我想比较C++类/结构对象。在C语言中,大多数时候,人们知道 struct 通过添加单个字段的大小(假定编译器不添加填充)。因此,可以在两个对象上使用memcmp()函数来快速比较它们。我不确定是否同样适用于C++。这是因为类也有函数定义,可能还有其他一些隐藏的东西(可能是一些rtti信息?甚至是一个虚拟函数表?)

    具有简单结构的快速程序,其中包含 int char 成员和函数表明结构的大小为 sizeof(int)+sizeof(char) .

    我有一个大的结构类,它有简单的int、char等数据类型(但有大量数据类型)。我想不时比较对象。我不能超载 == 运算符,因为这样可以使它们逐字段比较每个字段。在C语言中,我可以用 memcmp() . 对C++有什么建议吗?我能用吗? MEMPP() 直接?我不希望memcmp()失败,因为其他一些值(如虚拟函数指针表)是不同的(但所有字段实际上都是相等的) (我用的是G+)

    5 回复  |  直到 15 年前
        1
  •  10
  •   Jonathan Leffler    15 年前

    在很多方面都要小心…

    1. 任何填充中的值都是不确定的,因此不可比较。
    2. 如果您的机器是小尾数,比较整数字段将产生一个答案;如果您的机器是大尾数,将产生另一个答案。
    3. 大多数人认为-1小于0,但是 memcmp() 将执行逐字节无符号比较,因此将-1视为大于0。
    4. 从本质上讲,任何指标都不具有可比性。 MEMPP() .
    5. 你不能比较 float double 使用 MEMPP() .

    总的来说,你在寻求一种非理性的优化。

        2
  •  9
  •   Crashworks    15 年前

    有可能 sizeof() 结构或类。

    编辑: 既然我提供了上面的答案,你已经改变了你的问题:“我如何手动确定C++结构和类的大小?”关于比较两个类的更一般的一个。

    简短的回答是你 想要超载 == 操作员。认为它一次一个字段地比较每个字段是错误的;您可能会超载 operator == 使用任何你喜欢的算法,包括 memcmp .

    memcmp() 在内存上,从第一个字段偏移到最后一个字段应该可以正常工作。一 MEMPP() 如果将A类型的类与继承自A的另一个B类进行比较,则类的整个占用空间可能会失败,因为vtable指针可能不同。

        3
  •  3
  •   Alex Martelli    15 年前

    如果你 class struct 没有任何虚拟的,“添加单个字段的大小(假设编译器不添加填充)”在C++中与C一样正确(即不完全),因为填充 通常加;-)。

        4
  •  3
  •   Dolphin    15 年前

    P.O.D 与MECMP相比,S是安全的。

    填充对于在类对象上执行memcmp是一个问题,因为它可能被垃圾填充(这在对象之间是不同的)。在C中,通常不存在这个问题,因为在完成任何赋值之前将整个结构存储为0是很正常的,这在C++中是非常糟糕的,因为您可以重写VTABLE。

    我不相信语言规范中有任何说明如何实现vtables的内容,尽管它们通常是隐藏数据成员。对于同一类的成员,vtable应该是相同的(但对于父类/子类,当然是不同的)。当您进入多个或虚拟继承时,实现可能会因编译器而异。

        5
  •  0
  •   Andrew Garrison    15 年前

    据我所知,您可以使用pragma pack防止结构中的填充( gcc , vc++ )

    #pragma pack(push, 1)
    struct Example
    {
       int a;
       char b;
       short c;
    };
    #pragma pack(pop)
    

    打印sizeof(示例)显示它是7个字节。如果没有pragma包,大小为8字节。