【问题标题】:Why do both struct and class exist in C++?为什么 C++ 中同时存在结构和类?
【发布时间】:2016-04-26 15:56:16
【问题描述】:

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

POD 结构109 是一个非联合类,它既是 普通类和标准布局类,并且没有非静态数据 非 POD 结构、非 POD 联合(或此类数组)类型的成员 类型)。类似地,POD 联合 是一个既是平凡的联合 类和标准布局类,并且没有非静态数据成员 类型为非 POD 结构、非 POD 联合(或此类类型的数组)。一个POD class 是一个 POD 结构或 POD 联合的类。

简单来说,structclass 在以下情况下可以互换:

  • “类”声明
  • 范围枚举类型的声明
  • 详细的类型说明符,除非“类”是用union 声明的

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

template <struct T> // error

我看不出 structclass 之间有任何显着差异,即使在上面的 POD 示例中也是如此,因为标准中定义的 POD 结构 可以使用 @987654331 来声明@ 或 class

[class]/8 standard-layout struct 是一个标准布局类 用 class-key structclass-key class 定义。一种 standard-layout union 是使用 class-key union 定义的标准布局类。

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

我有两个问题:

  1. 我遗漏了哪些技术差异可以显着区分structclass

  2. 这种笨拙背后的基本原理是什么?

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

【问题讨论】:

  • 您是否也感到困惑,您可以拥有template&lt;typename T&gt;,但不能拥有typename T{};
  • @user2079303 和(在 C++1z 之前)template &lt; template&lt;typename&gt; class C &gt;,但不是 template &lt; template&lt;typename&gt; typename C &gt;
  • @Martin:不,OP 已经知道这些差异(他已经指出了它们)。
  • 我们能否把这个问题提高一个档次,询问标准是否真的规定了默认访问之外的差异?也就是说,如果您有两个标头,其中一个将类型声明为具有成员的struct T,另一个将其声明为具有所有公共成员的class T,两者都会 link 正确地链接到实现TT::... 成员的目标文件?

标签: c++ class struct standards


【解决方案1】:

为什么 C++ 中同时存在结构和类?

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

那么,为什么“C with Classes”会引入新的关键字class,而您可以使用struct 来做同样的事情,您可能会问。请参阅此SO answer 以获得合理的猜测。简而言之,这可能是因为希望强调OOP,其中class 是一个广泛使用的术语。只有 Stroustrup 可能知道。

令人困惑的是,关键字本身并不一定与标准中使用的语言相对应

需要理解的是,的概念与关键字class并不是一回事。

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

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

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

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

为什么struct 在上下文中不作为等价物使用,您可能会问。好吧,这是 Stroustrup 或委员会的另一个问题。这与委员会在引入enum class/enum struct 时所做的选择相反。

我看不出结构和类之间有什么显着的区别

很好。除了

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

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

  1. 是否存在我遗漏的显着区分结构和类的技术差异?

我已经回答过了,但需要明确的是,除了 之外,使用 structclass 关键字声明的类之间没有区别。

与默认访问说明符的区别(您已经知道,并且还描述了here),这是它们唯一的区别。

【讨论】:

  • 将“struct”限制为 PODS 声明,并说编译器没有义务将使用“class”声明的内容视为 POD,无论内容如何,​​会有任何不利吗?我认为这可以使许多其他规则更加清晰。
【解决方案2】:

为什么 C++ 中同时存在结构和类?

struct来自C,存在于C++中主要是为了与C编程语言兼容。

是否有任何我错过的技术差异 明显区分structclass

structclass 之间的主要区别在于,struct 的成员默认拥有public 访问权限,而class 的成员默认拥有private 访问权限。

p>

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

至于为什么不能使用 struct 关键字来指定非类型模板参数,原因是历史性的,我想你必须问 Bjarne :) 或参考这个 SO answer 了解后面的信息场景。

【讨论】:

  • 回答了一半。
  • 所有 C 程序都是有效的 C++ 程序,但并非所有 C++ 程序都是有效的 C 程序。没有理由不允许 template &lt;struct T&gt;,因为 C 中不存在模板。
  • @user5817092 All C programs are valid C++ programs不是正确的。一个典型的例子:int* p = malloc(n * sizeof(int))
  • 明确地说,我所指的另一半(未回答的一半)是关于为什么存在class,而不是第二个编号的问题。
  • @BenjaminLindley:我认为“复杂的 OOP 对象”应该是类,并且默认情况下将所有成员设为私有会迫使程序员考虑分配个人访问权限并只公开必要的内容,而不是全部公开
猜你喜欢
  • 2010-11-04
  • 1970-01-01
  • 2010-10-26
  • 1970-01-01
  • 2010-10-24
  • 1970-01-01
  • 2016-01-03
  • 2021-01-18
相关资源
最近更新 更多