C++ Class或Struct与C struct的兼容性

Cem*_*ncu 6 c++ class data-structures

是否可以编写与C结构完全兼容的C++类或结构.兼容性我指的是对象的大小和变量的内存位置.我知道使用它*(point*)&pnt甚至是邪恶(float*)&pnt(在不同的情况下,变量是浮点数),但考虑到性能需要它真正需要它.使用普通型铸造操作员每秒百万次是不合逻辑的.

举个例子

Class Point {
    long x,y;
    Point(long x, long y) {
        this->x=x;
        this->y=y;
    }

    float Distance(Point &point) {
        return ....;
    }
};
Run Code Online (Sandbox Code Playgroud)

C版本是POD结构

struct point {
    long x,y;
};
Run Code Online (Sandbox Code Playgroud)

Ste*_*eel 20

最干净的是要从C结构继承:

struct point
{
    long x, y;
};

class Point : public struct point
{
  public:
    Point(long x, long y)
        {    this->x=x; this->y=y; }

    float Distance(Point &point)
        {                return ....;        }
}
Run Code Online (Sandbox Code Playgroud)

C++编译器保证C样式结构点具有与C编译器相同的布局.C++类Point为其基类部分继承了这种布局(因为它不添加数据或虚拟成员,所以它将具有相同的布局).指向类Point的指针将转换为指向struct point的指针而不使用强制转换,因为始终支持转换为基类指针.因此,您可以使用类Point对象并自由地将指针传递给C函数,期望指向struct point的指针.

当然,如果已经有一个定义结构点的C头文件,那么你可以只包括它而不是重复定义.


Jas*_*ams 9

是.

  • 在两种语言中使用相同顺序的相同类型
  • 确保该类中没有任何虚拟内容(因此您不会在前面粘贴vtable指针)
  • 根据所使用的编译器,您可能需要调整结构包装(通常使用编译指示)以确保兼容性.

(编辑)

  • 此外,您必须注意使用编译器检查sizeof()类型.例如,我遇到了一个将短路存储为32位值的编译器(当大多数将使用16位时).更常见的情况是int在32位体系结构上通常为32位,在64位体系结构上通常为64位.


Key*_*oze 5

POD适用于C++.你可以拥有会员功能. "C++中的POD类型是一个聚合类,它只包含POD类型作为成员,没有用户定义的析构函数,没有用户定义的复制赋值运算符,也没有指向成员类型的非静态成员"

您应该设计POD数据结构,使它们具有自然对齐,然后可以在不同编译器在不同体系结构上创建的程序之间传递它们.自然对齐是任何成员的记忆偏移可以被该成员的大小整除的地方.IE:一个浮点位于一个可被4整除的地址,一个双重位于一个可被8整除的地址上.如果你声明一个字符后面跟一个浮点数,大多数架构将填充3个字节,但有些可以设想填充1个字节.如果你声明一个后跟一个char的浮点数,那么所有编译器(我应该为这个声明添加一个来源,对不起)都不会填充.