众所周知,struct
和class
在语言的许多地方都可以互换。令人困惑的是,关键字本身并不一定与标准中使用的语言相对应。例如,在草案标准N4567 [class] / 10,
POD结构 109 是一个非联合类,同时是一个 普通类和标准布局类,没有非静态数据 非POD结构类型的成员,非POD联合(或其类型的数组) 类型)。同样, POD联盟是一个既简单的联盟 class和标准布局类,没有非静态数据成员 类型为非POD结构,非POD联合(或此类型的数组)。一个 POD class 是一个POD结构或POD联合的类。
在过度简化的术语中,struct
和class
在以下情况下可以互换:
union
但是,struct
显式不能在模板声明中用于引入类型模板参数:
template <struct T> // error
即使在上面的POD示例中,我也无法看到struct
和class
之间存在任何显着差异,因为可以声明标准中定义的 POD结构使用struct
或class
。
[class] / 8 标准布局结构是标准布局类 使用 class-key struct 或 class-key class 定义。一个 标准布局联合是使用 class-key union 定义的标准布局类。
这引起了明显的不一致,似乎相当多余和令人困惑。
我有两个问题:
我是否遗漏了明显区分struct
和class
的技术差异?
这种笨拙背后的理由是什么?
我忽略了默认访问说明符之间的区别,因为每个人都已经知道了。
答案 0 :(得分:7)
为什么C ++中都存在struct和class?
struct
存在的原因是为了与C兼容。
为什么然后,当你可以使用class
来做同样的事情时,“C with Classes”会引入新关键字struct
,你可能会问。请参阅此SO answer以获得合理的推测。简而言之,可能是因为需要强调OOP class是一个广泛使用的术语。只有Stroustrup可以肯定地知道。
令人困惑的是,关键字本身并不一定与标准
中使用的语言相对应
需要理解的是,类的概念与关键字class
的概念不同。
声明类有三个关键字。这些称为类密钥的关键字是class
,struct
和union
。使用class
或struct
声明的非联合类完全相同,除了†。联盟类与非联盟类不同。
但是,struct显式不能在模板声明中用于引入类型模板参数
C ++在不同的上下文中为不同的目的重用关键字。类声明上下文中的class
关键字与模板参数定义中的class
关键字不完全相同。一个关键字在一个上下文中等同于另一个关键字并不会使其在所有上下文中都是等效的。在不同但相似的上下文中重用关键字的原因(static
是另一个例子),是为了避免引入新的关键字,这引入了更多与C(或更早的C ++标准)兼容且没有新关键字的漏洞。
为什么 class
关键字在模板类型参数的上下文中被重用的原因可能是因为类是类型,因此通常用作类型参数。还有一个typename
关键字,后来添加,并且(几乎)可以在模板类型参数声明中与class
互换,但也可以在其他地方使用(依赖类型名称)class
不是用过的。请参阅此answer以获取有关为何将单独的关键字添加到该上下文的链接和摘要。
为什么struct
不会在上下文中用作等效项,您可能会问。嗯,这是Stroustrup或委员会的另一个问题。这与委员会在引入enum class
/ enum struct
时的做法相反。
我无法看到struct和class之间存在任何显着差异
好。除†
外没有任何其他内容这引起了明显的不一致,似乎相当多余和令人困惑。
我认为标准的引用没有不一致。我看到冗余,我怀疑存在冗余,使得用关键字struct
声明的类仍然是一个类更清楚。
- 我是否遗漏了哪些技术差异可以明显区分结构和类?
醇>
我已经回答了,但很明显,除了†struct和class
关键字声明的类之间存在无差异>
†与默认访问说明符的差异(如您所知,并且还描述了here),这是唯一差异。
答案 1 :(得分:5)
为什么C ++中都存在struct和class?
struct
来自C,主要出于与C编程语言的兼容性而存在于C ++中。
我是否遗漏了任何技术差异 明显区分
struct
和class
?
struct
和class
之间的主要区别在于struct
其成员默认public
访问{} {} {}} {}默认情况下class
访问。
模板参数中使用的关键字private
不定义类,而是定义非类型模板参数,可以与关键字class
互换使用。
至于为什么你不能使用typename
关键字来指定非类型模板参数,原因是历史的,我想你必须向Bjarne询问它:)或者参考这个SO {{ 3}}用于幕后信息。