C++ C+的结构+;内存中的对象与结构

C++ C+的结构+;内存中的对象与结构,c++,struct,C++,Struct,如果我有如下的课程 class Example_Class { private: int x; int y; public: Example_Class() { x = 8; y = 9; } ~Example_Class() { } }; struct {

如果我有如下的课程

   class Example_Class 
   {
       private:
         int x; 
         int y; 
       public: 
         Example_Class() 
         { 
             x = 8;
             y = 9;
         }
       ~Example_Class() 
       { } 
   };
struct
{
   int x;
   int y;
} example_struct;
和一个结构,如下所示

   class Example_Class 
   {
       private:
         int x; 
         int y; 
       public: 
         Example_Class() 
         { 
             x = 8;
             y = 9;
         }
       ~Example_Class() 
       { } 
   };
struct
{
   int x;
   int y;
} example_struct;
example\u结构
的内存结构是否与
example\u类

例如,如果我执行以下操作

struct example_struct foo_struct;
Example_Class foo_class = Example_Class();

memcpy(&foo_struct, &foo_class, sizeof(foo_struct));
foo_struct.x=8
foo_struct.y=9
(即:与foo_类中的x,y值相同的值)

我问的原因是我有一个C++库(不想改变它),它用C代码共享一个对象,我想用一个Stutt来表示来自C++库的对象。我只对对象的属性感兴趣

我知道理想的情况是在C++和C++代码之间建立一个通用的结构,但是改变使用中的C++库是不容易的。 example_struct在内存中的结构是否与example_类中的结构相似

该行为不能保证,并且依赖于编译器


话虽如此,答案是“是的,在我的机器上”,前提是示例类不包含虚方法(并且不从基类继承)。

在您描述的情况下,答案是“可能是”。但是,如果该类具有任何虚拟函数(包括虚拟析构函数,可以从基类继承),或者使用多重继承,则类布局可能会有所不同。

要补充其他人所说的内容(例如:编译器特定的,只要没有虚拟函数,就可能工作):


如果您这样做的话,我强烈建议使用静态断言(编译时检查),即sizeof(Example_class)==sizeof(Example_struct)。请参阅BOOST_STATIC_ASSERT,或等效的编译器特定或自定义构造。如果有人(或某事,如编译器更改)修改类以使匹配无效,这是一条很好的第一道防线。如果您想额外检查,也可以运行时检查成员的偏移量是相同的,(与静态大小断言一起)将保证正确性。

< P> C++中的类和结构是等价的,除了结构的所有成员在默认情况下是公共的(默认情况下类成员是私有的)。这确保编译C++编译器中的遗留C代码将按预期工作。 < >没有什么可以阻止你使用结构中所有的奇特C++特性:

struct ReallyAClass
{
    ReallyAClass();
    virtual !ReallAClass();

    /// etc etc etc
};
<> P> C++标准保证了C <代码>结构> <代码>和C++ >代码>类< /代码>(或<代码>结构> /代码>相同的内容,只要C++ <代码>类< /COD>/<代码>结构> <代码>符合<>强> POD < /St>(“普通旧数据”)的标准。那么POD是什么意思呢

如果满足以下条件,则类或结构为POD:

  • 所有数据成员都是公共的,它们本身是POD或基本类型(但不是成员类型的引用或指针)或此类类型的数组
  • 它没有用户定义的构造函数、赋值运算符或析构函数
  • 它没有虚拟功能
  • 它没有基类
关于“C++-ISM”,只允许使用非虚拟成员函数、静态成员和成员函数

由于您的类既有构造函数又有析构函数,所以从形式上讲,它不是POD类型,因此保证不成立。(尽管,正如其他人所提到的,在实践中,只要没有虚拟函数,这两种布局在您尝试的任何编译器上都可能是相同的)


有关更多详细信息,请参见的[26.7]节。

当您要将数据传递给C时,为什么不显式地将类的成员分配给结构?这样你就知道你的代码可以在任何地方工作。

你可能只是从结构中派生出类,不管是公开的还是私下的。在C++ C++编译器的早期,编译器首先用类改变结构关键字,然后编译。有很多相似之处

差异来自类继承,特别是虚拟函数。若类包含虚函数,那个么它必须在布局的开头有一个指向类型描述符的指针。同样,如果类B继承自类A,那么类A的布局首先出现,然后是类B自己的布局

因此,关于将类实例强制转换为结构实例的问题的确切答案是:依赖于类内容。对于具有方法(构造函数和非虚拟析构函数)的特定类,布局可能是相同的。如果析构函数被声明为虚拟的,那么结构和类之间的布局肯定会有所不同

这是一篇文章,说明从C结构到C++类的步骤没有太多的需要:


这篇文章解释了虚拟函数表是如何引入具有虚拟函数的类:

我知道我可能不应该让我的解决方案依赖于体系结构,但是你使用的是什么机器/编译器?在这个例子中是保证的。我认为这个等价性只意味着你可以编译C代码作为C++。代码它们在某种程度上是“等价的”,但我怀疑(尽管我不知道)标准是否说它们的内存布局是相同的;此外,使用“虚拟”方法(如有缺陷的示例)可能会更改布局(通过向每个实例添加vptr)。所有常见编译器都会将vtable指针放在对象的开头,因此使用虚拟方法将改变类的内存布局。C++只对POD(“普通旧数据”)类型保证相同的行为:结构或类必须服从几个限制来分类为POD。删除我先前的注释,因为仔细考虑过,POD类的定义与C结构是可交换的。只是一个小注释,您的构造函数可以(也有人说应该)。可以这样写:Example_Class():x(8),y(9){}因为他使用的是一个单独的库,我认为