为什么C ++中都存在struct和class?

时间:2016-01-20 17:09:13

标签: c++ class struct standards

众所周知,structclass在语言的许多地方都可以互换。令人困惑的是,关键字本身并不一定与标准中使用的语言相对应。例如,在草案标准N4567 [class] / 10,

  

POD结构 109 是一个非联合类,同时是一个   普通类和标准布局类,没有非静态数据   非POD结构类型的成员,非POD联合(或其类型的数组)   类型)。同样, POD联盟是一个既简单的联盟   class和标准布局类,没有非静态数据成员   类型为非POD结构,非POD联合(或此类型的数组)。一个 POD   class 是一个POD结构或POD联合的类。

在过度简化的术语中,structclass在以下情况下可以互换:

  • 宣布“阶级”
  • 声明范围的枚举类型
  • 详细说明了类型说明符,除非使用union
  • 声明“class”

但是,struct 显式不能在模板声明中用于引入类型模板参数:

template <struct T> // error

即使在上面的POD示例中,我也无法看到structclass之间存在任何显着差异,因为可以声明标准中定义的 POD结构使用structclass

  

[class] / 8 标准布局结构是标准布局类   使用 class-key struct class-key class 定义。一个   标准布局联合是使用 class-key union 定义的标准布局类。

这引起了明显的不一致,似乎相当多余和令人困惑。

我有两个问题:

  1. 我是否遗漏了明显区分structclass的技术差异?

  2. 这种笨拙背后的理由是什么?

  3. 我忽略了默认访问说明符之间的区别,因为每个人都已经知道了。

2 个答案:

答案 0 :(得分:7)

  

为什么C ++中都存在struct和class?

struct存在的原因是为了与C兼容。

为什么然后,当你可以使用class来做同样的事情时,“C with Classes”会引入新关键字struct,你可能会问。请参阅此SO answer以获得合理的推测。简而言之,可能是因为需要强调OOP class是一个广泛使用的术语。只有Stroustrup可以肯定地知道。

  

令人困惑的是,关键字本身并不一定与标准

中使用的语言相对应

需要理解的是,的概念与关键字class的概念不同。

声明类有三个关键字。这些称为类密钥的关键字是classstructunion。使用classstruct声明的非联合类完全相同,除了。联盟类与非联盟类不同。

  

但是,struct显式不能在模板声明中用于引入类型模板参数

C ++在不同的上下文中为不同的目的重用关键字。类声明上下文中的class关键字与模板参数定义中的class关键字不完全相同。一个关键字在一个上下文中等同于另一个关键字并不会使其在所有上下文中都是等效的。在不同但相似的上下文中重用关键字的原因(static是另一个例子),是为了避免引入新的关键字,这引入了更多与C(或更早的C ++标准)兼容且没有新关键字的漏洞。

为什么 class关键字在模板类型参数的上下文中被重用的原因可能是因为类是类型,因此通常用作类型参数。还有一个typename关键字,后来添加,并且(几乎)可以在模板类型参数声明中与class互换,但也可以在其他地方使用(依赖类型名称)class不是用过的。请参阅此answer以获取有关为何将单独的关键字添加到该上下文的链接和摘要。

为什么struct不会在上下文中用作等效项,您可能会问。嗯,这是Stroustrup或委员会的另一个问题。这与委员会在引入enum class / enum struct时的做法相反。

  

我无法看到struct和class之间存在任何显着差异

好。除

外没有任何其他内容
  

这引起了明显的不一致,似乎相当多余和令人困惑。

我认为标准的引用没有不一致。我看到冗余,我怀疑存在冗余,使得用关键字struct声明的类仍然是一个类更清楚。

  
      
  1. 我是否遗漏了哪些技术差异可以明显区分结构和类?
  2.   

我已经回答了,但很明显,除了†struct和class关键字声明的类之间存在差异>

与默认访问说明符的差异(如您所知,并且还描述了here),这是唯一差异。

答案 1 :(得分:5)

  

为什么C ++中都存在struct和class?

struct来自C,主要出于与C编程语言的兼容性而存在于C ++中。

  

我是否遗漏了任何技术差异   明显区分structclass

structclass之间的主要区别在于struct其成员默认public访问{} {} {}} {}默认情况下class访问。

模板参数中使用的关键字private不定义类,而是定义非类型模板参数,可以与关键字class互换使用。

至于为什么你不能使用typename关键字来指定非类型模板参数,原因是历史的,我想你必须向Bjarne询问它:)或者参考这个SO {{ 3}}用于幕后信息。