两个相同类别的指针之间的铸造安全性?

时间:2011-10-14 04:09:46

标签: c++ pointers casting

假设我有两个不同的类,它们以相同的内部方式表示2D坐标数据,如下所示:

class LibA_Vertex{
    public:
    // ... constructors and various methods, operator overloads
    float x, y
};

class LibB_Vertex{
    public:
    // ... same usage and internal data as LibA, but with different methods
    float x, y
};


void foobar(){
    LibA_Vertex * verticesA = new LibA_Vertex[1000];
    verticesA[50].y = 9;
    LibB_Vertex * verticesB = reinterpret_cast<LibB_Vertex*>( vertexA );
    print(verticesB[50].y); // should output a "9"
};

鉴于两个类相同并且上面的函数,我可以可靠地指望这个指针转换在每种情况下按预期工作吗?

(背景,我需要一种简单的方法来交换两个具有相同Vertex类的独立库之间的顶点数组,我想避免不必要地复制数组。)

4 个答案:

答案 0 :(得分:13)

C ++ 11添加了一个名为 layout-compatible 的概念,适用于此处。

  

如果两个标准布局结构(第9条)类型具有相同数量的非静态数据成员和相应的非静态数据成员,则它们是布局兼容 (按照声明顺序)具有布局兼容类型(3.9)。

,其中

  

标准布局类是一个类:

     
      
  • 没有非标准布局类(或此类类型的数组)或引用类型的非静态数据成员,
  •   
  • 没有虚函数(10.3),没有虚基类(10.1),
  •   
  • 对所有非静态数据成员具有相同的访问控制(第11条),
  •   
  • 没有非标准布局基类
  •   
  • 在大多数派生类中没有非静态数据成员,并且最多只有一个具有非静态数据成员的基类,或者没有包含非静态数据成员的基类,并且
  •   
  • 没有与第一个非静态数据成员相同类型的基类。
  •   
     

标准布局结构是使用 class-key struct标准布局类 > class-key class

     

标准布局联合是使用 class-key union定义的标准布局类

最后

  

指向cv-qualified和cv-nonqualified version(3.9.3)的布局兼容的指针   类型应具有相同的值表示和对齐要求(3.11)。

保证reinterpret_cast可以将指向一种类型的指针转​​换为指向任何布局兼容类型的指针。

答案 1 :(得分:1)

我会把这个转换包装在一个类中(这样如果你需要更改平台或其他东西,它至少会在一个地方进行本地化)但是是的,它应该是可能的。

您还希望使用reinterpret_cast,而不是static_cast

答案 2 :(得分:1)

理论上这是一种未定义的行为。但是,它可能适用于某些系统/平台。

我建议您尝试将 2个类合并为1.即

class Lib_Vertex{
// data (which is exactly same for both classes)
public:
// methods for LibA_Vertex
// methods for LibB_Vertex
};

将方法添加到class不会影响其大小。您可能需要稍微改变一下设计,但这是值得的。

答案 3 :(得分:0)

从技术上讲,这是未定义的行为。实际上,如果使用相同的编译器来编译这两个类,如果字段以相同的顺序声明,具有相同的类型和相同的访问级别,它们在内存中将具有相同的布局。