C++:结构真的与类相同吗?

mad*_*adu 5 c++ struct class

可能的重复:
C++ 中的结构和类有什么区别

这个问题已经被问了很多次,也得到了很多回答,但每隔一段时间我就会遇到一些令人困惑的事情。

总而言之,C++ 结构和类之间的区别是著名的默认公共访问与私有访问。除此之外,C++ 编译器对待结构的方式与对待类的方式相同。结构体可以有构造函数、复制构造函数、虚函数。等等。结构的内存布局与类的内存布局相同。C++ 拥有结构体的原因是为了向后兼容 C。

现在,由于人们对使用结构体或类感到困惑,因此经验法则是,如果您只有普通的旧数据,请使用结构体。否则使用一个类。我读到结构在序列化方面很好,但不知道它来自哪里。

然后有一天我看到这篇文章:http://www.codeproject.com/Articles/468882/Introduction-to-a-Cplusplus-low-level-object-model

它说如果我们有(直接引用):

struct SomeStruct
{ 
    int    field1;
    char   field2;
    double field3;
    bool   field4; 
};  
Run Code Online (Sandbox Code Playgroud)

那么这个:

void SomeFunction()
{
    SomeStruct someStructVariable;
    // usage of someStructVariable
    ... 
}  
Run Code Online (Sandbox Code Playgroud)

和这个:

void SomeFunction()
{ 
    int    field1;
    char   field2;
    double field3;
    bool   field4;      
    // usage of 4 variables
    ... 
}
Run Code Online (Sandbox Code Playgroud)

是相同的。

它表示,如果我们有一个结构体或只写下函数内的变量,生成的机器代码是相同的。当然,这仅适用于您的结构是 POD 的情况。

这就是我感到困惑的地方。Scott Meyers 在《Effective C++》中说,不存在空类这样的东西。

如果我们有:

class EmptyClass { };
Run Code Online (Sandbox Code Playgroud)

它实际上是由编译器布局的,例如:

class EmptyClass
{
    EmptyClass() {}
    ~EmptyClass() {}
    ...
};
Run Code Online (Sandbox Code Playgroud)

所以你不会有一个空的班级。

现在,如果我们将上面的结构更改为类:

class SomeClass
{ 
    int  field1;
    char field2 
    double field3;
    bool  field4; 
}; 
Run Code Online (Sandbox Code Playgroud)

这是否意味着:

void SomeFunction()
{
    someClass someClassVariable;
    // usage of someClassVariable
    ... 
}  
Run Code Online (Sandbox Code Playgroud)

和这个:

void SomeFunction()
{ 
    int  field1;
    char field2 
    double field3;
    bool  field4;      
    // usage of 4 variables
    ... 
}
Run Code Online (Sandbox Code Playgroud)

机器指令相同吗?没有调用 someClass 构造函数?或者分配的内存与实例化类或单独定义变量相同?那么填充呢?结构和类进行填充。在这些情况下填充会相同吗?

如果有人能阐明这一点,我将非常感激。

Kir*_*lev 1

除了默认的保护之外,结构和类之间没有任何区别(请注意,基类的默认保护类型也不同)。书籍和我自己 20 多年的经验告诉了这一点。

关于默认的空ctor/ector。标准并没有要求这样做。然而,某些编译器可能会生成这对空的ctor/decor。每个合理的优化器都会立即丢弃它们。如果在某个地方调用了一个不执行任何操作的函数,您如何检测到这一点?除了消耗 CPU 周期之外,这还会有何影响?

MSVC 不会生成无用的函数。可以合理地认为每个好的编译器都会这样做。

关于示例

struct SomeStruct
{ 
    int    field1;
    char   field2;
    double field3;
    bool   field4; 
}; 

void SomeFunction()
{ 
    int    field1;
    char   field2;
    double field3;
    bool   field4;      
   ... 
}
Run Code Online (Sandbox Code Playgroud)

填充规则、内存中的顺序等可能并且很可能会完全不同。优化器可以很容易地丢弃未使用的局部变量。优化器从结构中删除数据字段的可能性要小得多(如果可能的话)。为此,结构应在 cpp 文件中定义,应设置某些标志等。

我不确定您是否会找到有关堆栈上本地变量填充的任何文档。AFAIK,这 100% 取决于编译器来制作此布局。相反,描述了结构/类的布局,有#pargma控制它的命令行键等。