可能重复:
What are the differences between struct and class in 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;
};
然后这个:
void SomeFunction()
{
SomeStruct someStructVariable;
// usage of someStructVariable
...
}
和此:
void SomeFunction()
{
int field1;
char field2;
double field3;
bool field4;
// usage of 4 variables
...
}
是一样的。
它表示如果我们有一个结构或只是写下函数内部的变量,生成的机器代码是相同的。当然,这只适用于你的结构如果是POD。
这是我感到困惑的地方。在Effective C ++中,Scott Meyers说没有空类。
如果我们有:
class EmptyClass { };
它实际上是由编译器编写的,例如:
class EmptyClass
{
EmptyClass() {}
~EmptyClass() {}
...
};
所以你不会有一个空课。
现在,如果我们将上述结构更改为类:
class SomeClass
{
int field1;
char field2
double field3;
bool field4;
};
是否意味着:
void SomeFunction()
{
someClass someClassVariable;
// usage of someClassVariable
...
}
和此:
void SomeFunction()
{
int field1;
char field2
double field3;
bool field4;
// usage of 4 variables
...
}
在机器说明方面是一样的吗?没有调用someClass构造函数?或者分配的内存与实例化类或单独定义变量相同?填充怎么样?结构和类做填充。在这些情况下,填充是否相同?
如果有人能够对此有所了解,我真的很感激。
答案 0 :(得分:2)
我认为该文章的作者是错误的。虽然可能两个函数的struct和非成员变量布局版本之间没有区别,但我不认为这是有保证的。我能想到的唯一可以保证的是,因为它是一个POD,结构的地址和第一个成员是相同的......并且每个成员在某个时刻之后会在内存中跟进。
在任何一种情况下,由于它是POD(并且类也可以,不要犯这样的错误),数据是否会被初始化。
我建议不要做出这样的假设。如果您编写了利用它的代码,并且我无法想象您为什么要这样做,那么大多数其他开发人员都会觉得它令人费解。只有你必须打破法律书籍。否则更喜欢以人们习惯的方式编码。所有这一切中唯一重要的部分是你应该记住POD对象没有被初始化,除非你明确这样做。
答案 1 :(得分:2)
唯一的区别是结构的成员默认是公共的,而类的成员默认是私有的(当我默认说,我的意思是“除非另有说明”)。看看这段代码:
#include <iostream>
using namespace std;
struct A {
int x;
int y;
};
class A obj1;
int main() {
obj1.x = 0;
obj1.y = 1;
cout << obj1.x << " " << obj1.y << endl;
return 0;
}
代码编译并运行得很好。
答案 2 :(得分:1)
除了保护的默认值之外,结构和类之间没有区别(请注意,基类的默认保护类型也不同)。书籍和我20多年的经验告诉我们。
关于默认的空ctor / dector。标准不是要求这个。然而,一些编译器可能会生成这对空的ctor / dector。每个合理的优化器都会立即抛弃它们。如果在某个地方调用无效的函数,你怎么能检测到这个?除了消耗CPU周期之外,这会如何影响任何事情?
MSVC没有生成无用的功能。认为每个好的编译器都会这样做是合理的。
关于例子
struct SomeStruct
{
int field1;
char field2;
double field3;
bool field4;
};
void SomeFunction()
{
int field1;
char field2;
double field3;
bool field4;
...
}
填充规则,内存顺序等可能并且很可能完全不同。优化器可能很容易丢弃未使用的局部变量。更不可能(如果可能的话)优化器将从结构中删除数据字段。为此,结构应该在cpp文件中定义,应该设置某些标志等等。
我不确定您是否会在堆栈上找到有关填充本地变量的任何文档。 AFAIK,这是制作此布局的100%编译器。相反,描述了结构/类的布局,有#pargma
和控制它的命令行键等。
答案 3 :(得分:1)
在机器说明方面是一样的吗?
没有理由不这样做。但是标准没有保证。
没有调用someClass构造函数?
是的,有一个对构造函数的调用。但构造函数不起作用(因为所有成员都是POD,并且您声明someClass someClassVariable;
的方式导致值初始化,这对POD成员没有任何作用)。因此,由于没有工作要做,所以不需要提供任何指示。
或者分配的内存与实例化类或单独定义变量相同?
该类可能包含填充,单独声明变量。
此外,我确信编译器可以更轻松地优化各个变量。
那么填充呢?
是的,结构(struct / class)中可能存在填充。
结构和类做填充。在这些情况下,填充是否相同?
是。只要确保你比较苹果和苹果(即)
struct SomeStruct
{
int field1;
char field2;
double field3;
bool field4;
};
class SomeStruct
{
public: /// Make sure you add this line. Now they are identical.
int field1;
char field2;
double field3;
bool field4;
};