为什么结构体和类都存在于C++中
Why do both struct and class exist in C++?
众所周知,struct
和class
在语言的许多地方是可以互换的。令人困惑的是,关键字本身并不一定与标准中使用的语言相对应。例如,在标准草案 N4567 [class]/10 中,
POD 结构体 109 是一个非联合类,它既是 平凡类和标准布局类,并且没有非静态数据 非 POD 结构、非 POD 联合(或此类数组)类型的成员 类型)。同样,POD 联合是一个既微不足道的联合 类和标准布局类,并且没有非静态数据成员 非 POD 结构、非 POD 联合(或此类类型的数组)的类型。一个豆荚 类是作为 POD 结构或 POD 联合的类。
在过于简化的术语中,struct
和class
在以下情况下可以互换:
- "类"的声明
- 作用域枚举类型的声明
- 详细的类型说明符,除非"类"声明为
union
但是,struct
不能在模板声明中显式用于引入类型模板参数:
template <struct T> // error
即使在上面的 POD 示例中,我也看不到 struct
和 class
之间的任何显着区别,因为标准中定义的 POD 结构可以用 struct
或 class
声明。
[类]/8 标准布局结构是标准布局类 使用类键结构或类键类定义。一个 标准布局联合是使用类键联合定义的标准布局类。
这似乎相当多余和令人困惑,同时引入了明显的不一致。
我有两个问题:
我错过了任何显着区分
struct
和class
的技术差异吗?这种笨拙背后的理由是什么?
我忽略了默认访问说明符之间的区别,因为每个人都已经知道了。
为什么结构体和类都存在于C++?
struct
存在的原因是为了与 C 兼容。
那么,为什么"C with Classes"引入了新的关键字class
,而你可以将struct
用于同样的事情,你可能会问。请参阅此SO答案以获取合理的猜测。简而言之,这可能是因为人们希望强调OOP,其中类是一个广泛使用的术语。只有斯特劳斯特鲁普可能确切知道。
令人困惑的是,关键字本身并不一定与标准中使用的语言相对应
需要理解的是,类的概念与关键字class
不是一回事。
用于声明类的关键字。这些被称为类键的关键字是class
、struct
和union
。使用 class
或 struct
声明的非联合类完全相同,除了 †。工会班级不同于非工会班级。
但是,不能在模板声明中显式使用结构来引入类型模板参数
C++在不同的上下文中为不同的目的重复使用关键字。 类声明上下文中的class
关键字与模板参数定义中的class
关键字不完全相同。一个关键字在一个上下文中等效于另一个关键字并不能使其在所有上下文中都等效。在不同但相似的上下文中重用关键字static
的原因是为了避免引入新关键字,这会引入更多与没有新关键字的 C(或更早C++标准)兼容的漏洞。
class
关键字在模板类型参数的上下文中重用的原因可能是因为类是类型,因此通常用作类型参数。还有一个typename
关键字,它是后来添加的,(几乎)可以与模板类型参数声明中的class
互换,但也用于不使用class
的其他地方(依赖类型名称)。有关将单独的关键字添加到该上下文的原因的链接和摘要,请参阅此答案。
您可能会问,为什么struct
在上下文中不用作等价物。好吧,这是Stroustrup或委员会的另一个问题。这与引入enum class
/enum struct
时委员会所做的相反。
我看不出结构体和类之间有任何显着差异
好。除了†之外,没有任何
这似乎相当多余和令人困惑,同时引入了明显的不一致。
我认为标准的引用没有不一致之处。我看到了冗余,我怀疑冗余的存在是为了更加清楚地表明使用关键字 struct
声明的类仍然是一个类。
- 我是否遗漏了任何显着区分结构和类的技术差异?
我已经回答了,但需要明确的是,除了†之外,用struct
和class
关键字声明的类之间没有区别。
†与默认访问说明符的区别(如您所知,也在此处进行了描述),这是它们唯一的区别。
为什么结构体和类都存在于C++?
struct
来自 C,主要出于与 C 编程语言兼容的原因而存在于C++中。
我错过了任何技术差异吗 显著区分
struct
和class
?
struct
和class
之间的主要区别在于,对于struct
,其成员默认具有public
访问权限,而对于class
,其成员默认具有private
访问权限。
模板参数中使用的关键字class
不定义类,而是定义非类型模板参数,并且可以与关键字 typename
互换使用。
至于为什么你不能使用struct
关键字来指定非类型模板参数,原因是历史的,我想你必须问 Bjarne :)或参考此 SO 答案以获取幕后信息。
- C++模板来检查友元函数的存在
- 既然存在危险,为什么项目要使用-I include开关
- 我们可以访问一个不存在的联盟的成员吗
- C++:对不存在的命名空间使用命名空间指令
- C++quit()函数中可能存在作用域问题
- C++擦除(如果存在)
- g++ 说函数不存在,即使包含正确的标头
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 有了gcc,是否可以链接库,但前提是它存在
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数
- gcc和clang在表达式是否为常量求值的问题上存在分歧
- C++Builder中的OnClick事件签名存在问题
- 如何正确地将分支添加到已存在的树中
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 如何检查QList中是否存在值
- 根据某个函数是否存在启用模板
- 如何将分支添加到已存在的TTree:ROOT
- 地图计数确实很重要,或者只是检查是否存在
- 通用C++/Python 多语言的存在
- 为什么我的共享库中存在展开符号