在c++中,在哪些情况下使用结构体比使用类更好?


当前回答

它们几乎是一样的。由于c++的魔力,结构体可以像类一样保存函数、使用继承、使用“new”创建等等

唯一的功能区别是类以私有访问权限开始,而结构以public开始。这是对C语言的向后兼容。

在实践中,我总是使用结构体作为数据持有者,类作为对象。

其他回答

正如每个人所说,唯一真正的区别是默认访问。但是,当我不想对简单的数据类进行任何形式的封装时,即使实现了一些helper方法,我也会特别使用struct。例如,当我需要这样的东西时:

struct myvec {
    int x;
    int y;
    int z;

    int length() {return x+y+z;}
};

回答我自己的问题(无耻地),正如已经提到的,访问权限是c++中它们之间的唯一区别。

我倾向于仅将结构体用于数据存储。我将允许它获得一些帮助函数,如果它使处理数据更容易的话。然而,一旦数据需要流控制(即维护或保护内部状态的getter /setter)或开始获得任何主要功能(基本上更像对象),它将被“升级”为一个类,以更好地传达意图。

只是从c++ 20 standard的角度(从N4860工作)来解决这个问题…

类是一种类型。关键字“class”和“struct”(以及“union”)在c++语法中是“class-key”,选择class或struct的唯一功能意义是:

类键决定是否…默认情况下访问是public或private(11.9)。

数据成员默认可访问性

class关键字的结果是private-by-default成员,而' struct关键字的结果是public-by-default成员,在11.9.1的例子中有说明:

类X { int;// X::a默认为private:使用的类

对…

struct S { int;// S::a默认为public: struct被使用

基类默认可访问性

1.9还说:

在基类没有访问说明符的情况下,当派生类使用类键结构体定义时假定为public,当类使用类键类定义时假定为private。

需要一致使用结构体或类的情况……

有一个要求:

在类模板的重声明、部分特化、显式特化或显式实例化中,类键应与原始类模板声明一致(9.2.8.3)。

...在任何详细类型说明符中,枚举关键字应使用指向枚举(9.7.1),联合类键应使用指向联合(11.5),类或结构的类键必须是 用于指非并体类(11.1)。

以下是不需要一致性的例子:

struct S {} S; 类S* p = &s;/ /好吧

不过,一些编译器可能会对此提出警告。


有趣的是,虽然你用struct、class和union创建的类型都被称为“类”,但我们有…

标准布局结构体是用类键结构体或类键类定义的标准布局类。

...所以在标准语中,当谈到标准布局结构体时,它使用“struct”来暗示“不是联合”。

我很好奇在其他术语中是否也有类似的“struct”用法,但要对标准进行详尽的搜索,工作量太大了。欢迎对此发表评论。

在用我的主要语言c++编程多年之后,我得出了一个死结论,那就是这是c++的另一个愚蠢的特性。

两者之间没有真正的区别,我也没有理由花额外的时间来决定是应该将实体定义为结构体还是类。

要回答这个问题,请随时将实体定义为结构。默认情况下,成员将是公开的,这是规范。但更重要的是,默认情况下继承将是公开的。受保护继承和更糟糕的私有继承是例外。

我从来没有遇到过私人继承是正确做法的案例。是的,我试图发明问题来使用私有继承,但它不起作用。如果不使用访问器关键字,面向对象编程的角色模型Java默认为公共继承。顺便提一下,Java不允许在继承类上访问关键字,它们只能被公开继承。所以你可以看到,cpp团队在这里真的很失败。

另一件令人沮丧的事情是,如果你定义为类,声明为结构,你会得到编译警告。就好像这是影响程序性能或准确性的东西一样。一个回答还指出,MSVC可能会产生编译器错误。

Those persons that use classes when it is raining and structs when it is shining are doing so based on what they have been taught. It's not something they discovered to be true. Java does not have a pair of names for classes, and only have the class keyword. If you want a data structure, simply make all your members public and don't add functions. This works in Java and I don't see any problem. What's the problem? You need 4 or 5 characters of BOM code to determine how to interpret the context of a class entity.

当你用c++实现提供兼容C的接口时,struct(更一般地说是PODs)非常方便,因为它们可以跨语言边界和链接器格式移植。

如果您不关心这一点,那么我认为使用“struct”而不是“class”是一种很好的意图交流方式(如上面的@ZeroSignal所述)。struct还具有更可预测的复制语义,因此对于打算写入外部媒体或通过网络发送的数据非常有用。

struct对于各种元编程任务也很方便,比如trait模板只暴露了一堆依赖的typedef:

template <typename T> struct type_traits {
  typedef T type;
  typedef T::iterator_type iterator_type;
  ...
};

...但这实际上只是利用了struct的默认保护级别是公共的……