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


当前回答

当你用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的默认保护级别是公共的……

其他回答

我唯一一次使用结构体而不是类是在函数调用中使用函数子之前声明函数子,为了清晰起见,我想尽量减少语法。例如:

struct Compare { bool operator() { ... } };
std::sort(collection.begin(), collection.end(), Compare()); 

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中所做的事情相同,但我发现必须将消息解码为类的开销通常是不值得的。

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

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

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

现有的答案中有很多误解。

class和struct都声明一个类。

是的,您可能必须在类定义中重新安排访问修改关键字,这取决于您用于声明类的关键字。

但是,除了语法之外,选择一种而不是另一种的唯一原因是惯例/风格/偏好。

有些人喜欢对没有成员函数的类坚持使用struct关键字,因为最终的定义“看起来像”C中的简单结构。

类似地,有些人喜欢对具有成员函数和私有数据的类使用class关键字,因为它表示“类”,因此看起来像他们最喜欢的面向对象编程书籍中的示例。

实际上,这完全取决于您和您的团队,这对您的程序没有任何影响。

下面这两个类除了名字以外在其他方面都是完全等价的:

struct Foo
{
   int x;
};

class Bar
{
public:
   int x;
};

你甚至可以在重新声明时切换关键字:

class Foo;
struct Bar;

(虽然这将破坏Visual Studio构建由于不一致,所以编译器将发出一个警告,当你这样做。)

下面的表达式都为true:

std::is_class<Foo>::value
std::is_class<Bar>::value

不过,请注意,在重新定义时不能切换关键字;这只是因为(根据单定义规则)跨翻译单元的重复类定义必须“由相同的标记序列组成”。这意味着你甚至不能交换const int成员;,并且与类或结构的语义无关。

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