什么时候应该在 C++ 中使用类和结构?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/54585/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 12:30:34  来源:igfitidea点击:

When should you use a class vs a struct in C++?

c++oopclassstructooad

提问by Alan Hinchcliffe

In what scenarios is it better to use a structvs a classin C++?

在什么情况下在 C++ 中使用 astruct和 a更好class

采纳答案by Commodore Jaeger

Differences between a classand a structin C++ are that structs have default publicmembers and bases and classes have default privatemembers and bases. Both classes and structs can have a mixture of public, protectedand privatemembers, can use inheritance and can have member functions.

C++ 中aclass和 a之间的区别在于struct结构具有默认public成员和基类,而类具有默认private成员和基类。两个类和结构可具有的混合物publicprotectedprivate构件,可以使用继承并且可以具有成员函数。

I would recommend using structs as plain-old-data structures without any class-like features, and using classes as aggregate data structures with privatedata and member functions.

我建议将结构用作没有任何类特征的普通旧数据结构,并将类用作具有private数据和成员函数的聚合数据结构。

回答by quark

As everyone else notes there are really only two actual language differences:

正如其他人所指出的,实际上只有两种实际的语言差异:

  • structdefaults to public access and classdefaults to private access.
  • When inheriting, structdefaults to publicinheritance and classdefaults to privateinheritance. (Ironically, as with so many things in C++, the default is backwards: publicinheritance is by far the more common choice, but people rarely declare structs just to save on typing the "public" keyword.
  • struct默认为公共访问,class默认为私有访问。
  • 继承时,struct默认为public继承,class默认为private继承。(具有讽刺意味的是,与 C++ 中的许多事情一样,默认值是向后的:public继承是迄今为止更常见的选择,但人们很少声明structs 只是为了节省键入 " public" 关键字。

But the real difference in practice is between a class/structthat declares a constructor/destructor and one that doesn't. There are certain guarantees to a "plain-old-data" POD type, that no longer apply once you take over the class's construction. To keep this distinction clear, many people deliberately only use structs for POD types, and, if they are going to add any methods at all, use classes. The difference between the two fragments below is otherwise meaningless:

但在实践中,真正的差别是间class/struct声明构造函数/析构函数不和的。对“纯旧数据”POD 类型有一定的保证,一旦您接管类的构造,就不再适用。为了保持这种区别,许多人故意只将structs 用于 POD 类型,并且,如果他们要添加任何方法,请使用classes。下面两个片段之间的区别是没有意义的:

class X
{
  public:

  // ...
};

struct X
{
  // ...
};

(Incidentally, here's a thread with some good explanations about what "POD type" actually means: What are POD types in C++?)

(顺便说一句,这里有一个线程很好地解释了“POD 类型”的实际含义:什么是 C++ 中的 POD 类型?

回答by Lightness Races in Orbit

There are lots of misconceptions in the existing answers.

现有答案中有很多误解。

Both classand structdeclare a class.

双方classstruct声明一个类。

Yes, you may have to rearrange your access modifying keywords inside the class definition, depending on which keyword you used to declare the class.

是的,您可能需要在类定义中重新排列访问修改关键字,具体取决于您用于声明类的关键字。

But, beyond syntax, the onlyreason to choose one over the other is convention/style/preference.

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

Some people like to stick with the structkeyword for classes without member functions, because the resulting definition "looks like" a simple structure from C.

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

Similarly, some people like to use the classkeyword for classes with member functions and privatedata, because it says "class" on it and therefore looks like examples from their favourite book on object-oriented programming.

类似地,有些人喜欢对class带有成员函数和private数据的类使用关键字,因为它上面写着“类”,因此看起来就像他们最喜欢的面向对象编程书中的例子。

The reality is that this completely up to you and your team, and it'll make literally no difference whatsoever to your program.

现实情况是,这完全取决于您和您的团队,这对您的计划没有任何影响。

The following two classes are absolutely equivalent in every way except their name:

除了名称之外,以下两个类在各方面都绝对等效:

struct Foo
{
   int x;
};

class Bar
{
public:
   int x;
};

You can even switch keywords when redeclaring:

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

class Foo;
struct Bar;

(although this breaks Visual Studio buildsdue to non-conformance, so that compiler will emit a warning when you do this.)

(尽管这会由于不符合而中断 Visual Studio 构建,因此编译器会在您执行此操作时发出警告。)

and the following expressions both evaluate to true:

并且以下表达式的计算结果均为 true:

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

Do note, though, that you can't switch the keywords when redefining; this is only because (per the one-definition rule) duplicate class definitions across translation units must "consist of the same sequence of tokens". This means you can't even exchange const int member;with int const member;, and has nothing to do with the semantics of classor struct.

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

回答by Ferruccio

The only time I use a struct instead of a class is when declaring a functor right before using it in a function call and want to minimize syntax for the sake of clarity. e.g.:

我唯一一次使用结构而不是类是在函数调用中使用它之前声明一个函子,并且为了清晰起见想要最小化语法。例如:

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

回答by Tal Pressman

From the C++ FAQ Lite:

来自C++ FAQ Lite

The members and base classes of a struct are public by default, while in class, they default to private. Note: you should make your base classes explicitly public, private, or protected, rather than relying on the defaults.

struct and class are otherwise functionally equivalent.

OK, enough of that squeaky clean techno talk. Emotionally, most developers make a strong distinction between a class and a struct. A struct simply feels like an open pile of bits with very little in the way of encapsulation or functionality. A class feels like a living and responsible member of society with intelligent services, a strong encapsulation barrier, and a well defined interface. Since that's the connotation most people already have, you should probably use the struct keyword if you have a class that has very few methods and has public data (such things do exist in well designed systems!), but otherwise you should probably use the class keyword.

结构体的成员和基类默认是公共的,而在类中,它们默认是私有的。注意:您应该使您的基类明确公开、私有或受保护,而不是依赖于默认值。

struct 和 class 在其他方面在功能上是等效的。

好的,足够干净的技术谈话。在情感上,大多数开发人员在类和结构之间做出了很大的区分。结构体感觉就像一堆开放的位,几乎没有封装或功能。一个类就像一个有生命的、负责任的社会成员,拥有智能服务、强大的封装屏障和定义明确的接口。由于这是大多数人已经拥有的含义,如果您有一个方法很少且具有公共数据的类(这种东西确实存在于设计良好的系统中!),您可能应该使用 struct 关键字,否则您可能应该使用该类关键词。

回答by mbyrne215

One place where a struct has been helpful for me is when I have a system that's receiving fixed format messages (over say, a serial port) from another system. You can cast the stream of bytes into a struct that defines your fields, and then easily access the fields.

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);
}

Obviously, this is the same thing you would do in C, but I find that the overhead of having to decode the message into a class is usually not worth it.

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

回答by Adisak

You can use "struct" in C++ if you are writing a library whose internals are C++ but the API can be called by either C or C++ code. You simply make a single header that contains structs and global API functions that you expose to both C and C++ code as this:

如果您正在编写内部为 C++ 但 API 可由 C 或 C++ 代码调用的库,则可以在 C++ 中使用“struct”。您只需创建一个包含结构体和全局 API 函数的头文件,您可以将这些函数公开给 C 和 C++ 代码,如下所示:

// C access Header to a C++ library
#ifdef __cpp
extern "C" {
#endif

// Put your C struct's here
struct foo
{
    ...
};
// NOTE: the typedef is used because C does not automatically generate
// a typedef with the same name as a struct like C++.
typedef struct foo foo;

// Put your C API functions here
void bar(foo *fun);

#ifdef __cpp
}
#endif

Then you can write a function bar() in a C++ file using C++ code and make it callable from C and the two worlds can share data through the declared struct's. There are other caveats of course when mixing C and C++ but this is a simplified example.

然后,您可以使用 C++ 代码在 C++ 文件中编写函数 bar() 并使其可从 C 调用,这两个世界可以通过声明的结构共享数据。在混合 C 和 C++ 时当然还有其他注意事项,但这是一个简化的示例。

回答by ogoid

As every one says, the only real difference is the default access. But I particularly use struct when I don't want any sort of encapsulation with a simple data class, even if I implement some helper methods. For instance, when I need something like this:

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

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

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

回答by Alan Hinchcliffe

To answer my own question (shamelessly), As already mentioned, access privileges are the only difference between them in C++.

回答我自己的问题(无耻地),如前所述,访问权限是它们在 C++ 中的唯一区别。

I tend to use a struct for data-storage only. I'll allow it to get a few helper functions if it makes working with the data easier. However as soon as the data requires flow control (i.e. getters/setters that maintain or protect an internal state) or starts acquring any major functionality (basically more object-like), it will get 'upgraded' to a class to better communicate intent.

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

回答by argv0

Structs (PODs, more generally) are handy when you're providing a C-compatible interface with a C++ implementation, since they're portable across language borders and linker formats.

当您使用 C++ 实现提供与 C 兼容的接口时,结构(更一般地说是POD)很方便,因为它们可以跨语言边界和链接器格式移植。

If that's not a concern to you, then I suppose the use of the "struct" instead of "class" is a good communicator of intent (as @ZeroSignal said above). Structs also have more predictable copying semantics, so they're useful for data you intend to write to external media or send across the wire.

如果这不是你关心的问题,那么我认为使用“struct”而不是“class”是一个很好的意图沟通者(如@ZeroSignal 上面所说)。结构还具有更可预测的复制语义,因此它们对于您打算写入外部媒体或通过网络发送的数据很有用。

Structs are also handy for various metaprogramming tasks, like traits templates that just expose a bunch of dependent typedefs:

结构对于各种元编程任务也很方便,比如只公开一堆依赖类型定义的特征模板:

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

...But that's really just taking advantage of struct's default protection level being public...

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