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


当前回答

从技术上讲,这两者在c++中是相同的——例如,结构体可能具有重载操作符等。

然而:

当我希望同时传递多种类型的信息时,我使用结构体 当我处理一个“功能性”对象时,我使用类。

希望能有所帮助。

#include <string>
#include <map>
using namespace std;

struct student
{
    int age;
    string name;
    map<string, int> grades
};

class ClassRoom
{
    typedef map<string, student> student_map;
  public :
    student getStudentByName(string name) const 
    { student_map::const_iterator m_it = students.find(name); return m_it->second; }
  private :
    student_map students;
};

例如,我在这里的get…()方法中返回一个struct student -喜欢。

其他回答

只是从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”用法,但要对标准进行详尽的搜索,工作量太大了。欢迎对此发表评论。

正如其他人指出的那样

除了默认可见性之外,两者都是等效的 无论出于什么原因,都可能有理由被迫使用其中一种或另一种

关于何时使用Stroustrup/Sutter给出了明确的建议:

如果类有不变量,则使用class;如果数据成员可以独立变化,则使用struct

然而,请记住,将某事物前向声明为类(class X;)并将其定义为struct (struct X{…})。 它可能在某些链接器上工作(例如g++),但可能在其他链接器上失败(例如MSVC),所以你会发现自己陷入了开发人员的地狱。

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

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

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

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

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

struct对我有帮助的一个地方是,当我有一个系统从另一个系统接收固定格式的消息(通过串行端口)时。您可以将字节流转换为定义字段的结构,然后轻松访问这些字段。

typedef struct
{
    int messageId;
    int messageCounter;
    int messageData;
} tMessageType;

void processMessage(unsigned char *rawMessage)
{
    tMessageType *messageFields = (tMessageType *)rawMessage;
    printf("MessageId is %d\n", messageFields->messageId);
}

显然,这与您在C中所做的事情相同,但我发现必须将消息解码为类的开销通常是不值得的。